Как я могу использовать специализацию шаблона для поиска типов аргументов функций-членов и т. Д.? - PullRequest
3 голосов
/ 20 января 2012

Я уверен, что видел описанное ранее, но не могу найти его сейчас.

Учитывая класс с функцией-членом некоторой формы, например:

int Foo::Bar(char, double)

Как я могу использовать шаблон и различные специализации для определения составных типов, например:

template<typename Sig>
struct Types;

// specialisation for member function with 1 arg
template<typename RetType, typename ClassType, etc...>
struct Types<RetType (ClassType::*MemFunc)(Arg0)>
{
    typedef RetType return_type;
    typedef ClassType class_type;
    typedef MemFunc mem_func;
    typedef Arg0 argument_0;
    etc...
};

// specialisation for member function with 2 args
template<typename RetType, typename ClassType, etc...>
struct Types<RetType (ClassType::*MemFunc)(Arg0, Arg1)>
{
    typedef RetType return_type;
    typedef ClassType class_type;
    typedef MemFunc mem_func;
    typedef Arg0 argument_0;
    typedef Arg0 argument_1;
    etc...
};

Так, чтобы при создании экземпляра Types с помощью моей функции-члена выше, например:

Types<&Foo::Bar>

он разрешает правильную специализацию и объявляет соответствующие typedefs?

Редактировать:

Я играю с fast-делегатами с обратным вызовом, статически связанным с функцией-членом,

У меня есть следующий макет, который, по моему мнению, статически привязывается к функции-члену:

#include <iostream>

template<class class_t, void (class_t::*mem_func_t)()>
struct cb
{
    cb( class_t *obj_ )
        : _obj(obj_)
    { }

    void operator()()
    {
      (_obj->*mem_func_t)();
    }

    class_t *_obj;
};

struct app
{
  void cb()
  {
    std::cout << "hello world\n";
  }
};

int main()
{
  typedef cb < app, &app::cb > app_cb;

  app* foo = new app;
  app_cb f ( foo );
  f();
}

Однако - как получить это как специализацию описанным выше способом?

1 Ответ

4 голосов
/ 20 января 2012

Вы почти получили его, за исключением этого дополнительного MemFunc, который не является частью типа.

template<typename RetType, typename ClassType, typename Arg0>
struct Types<RetType (ClassType::*)(Arg0)>   // <-- no MemType
{
    typedef RetType return_type;
    typedef ClassType class_type;
//  typedef MemFunc mem_func;     // <-- remove this line
    typedef Arg0 argument_0;
};

Тем не менее, вы не можете использовать

Types<&Foo::Bar>

потому что Foo :: Bar является указателем на функцию-член, а не на его тип.Вам понадобятся некоторые расширения компилятора, чтобы получить тип в C ++ 03, например typeof в gcc или Boost.Typeof :

Types<typeof(&Foo::Bar)>

илиобновить до C ++ 11 и использовать стандарт decltype:

Types<decltype(&Foo::Bar)>
...