2012-01-19 2 views
3

Я уверен, что видел это ранее, но не могу, чтобы жизнь меня нашла сейчас.Как я могу использовать специализированную специализацию для поиска типов аргументов функции-члена и т. Д.?

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

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<&Foo::Bar> 

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

Edit:

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

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

#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(); 
} 

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

ответ

4

Вы почти получили его, за исключением того, что дополнительный 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 in gcc или Boost.Typeof:

Types<typeof(&Foo::Bar)> 

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

Types<decltype(&Foo::Bar)> 
+0

, к сожалению, вся суть этого упражнения заключается в том, что я хочу, чтобы статически привязать к функции члена, так что оптимизатор может так оптимизировать через границу указателя функции. Будет ли использовать decltype для этого? –

+0

'decltype' возвращает тип объекта, а не сам указатель. Вы пытаетесь сделать [быстрый делегат] (http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx)? – kennytm

+0

Я действительно - см. Редактирование вопроса. благодаря –

Смежные вопросы