Ответ 1
Вы, вероятно, должны просто написать имя класса там. Однако, если вы действительно хотите избежать этого, вы можете использовать злую магию макросов. Простая версия более опасна:
#define TT(X) decltype(X), X
template<typename T,T t>
struct Foo
{ /* ... */ };
struct Bar {
int fun(float) {}
};
int main() {
Foo<TT(&Bar::fun)> f;
}
Это будет принимать любые параметры шаблона непигового типа, и вы можете столкнуться с трудными для понимания ошибками, если реализация Foo
работает только с указателями на член.
Чтобы сделать его более безопасным, вам понадобится метафейс, который сообщает вам имя класса:
template<typename T> struct member_ptr_traits;
template<typename Class,typename Ret,typename... Args>
struct member_ptr_traits<Ret (Class::*)(Args...)>
{
typedef Class class_type;
typedef Ret return_type;
};
#define TT(X) member_ptr_traits<decltype(X)>::class_type , X
template<typename T,int (T::*FUN)(float)>
struct Foo
{ /* ... */ };
struct Bar {
int fun(float) {}
};
int main() {
Foo<TT(&Bar::fun)> f;
}
Также оба из них используют С++ 11, поэтому они не будут работать со старыми компиляторами. Эта простая версия может быть переписана для использования старых typeof
или подобных расширений компилятора. Переписывание более безопасной версии требует моделирования вариативных шаблонов.