我在玩弄玩家。我正在使用下面的标准示例:
class C {
public:
template <typename Func>
void foo(Func fun)
{
fun();
}
};
struct S {
void operator()() { printf ("in S\n"); }
};
....
C myClass;
myClass.foo (S());
这很好用,我不需要在调用foo()时显式提供S模板类型,它只是想出来。但是假设我想将仿函数存储为成员变量并稍后调用它:
class C {
public:
template <typename Func>
void foo(Func fun) {
_myFunc = fun;
}
void someOtherThing() {
_myFunc();
}
private:
WHAT_IS_THIS_TYPE _myFunc;
};
我现在需要让整个班级成为模板吗?如果是这样,编译器可以像使用单个仿函数一样推断模板类型,还是必须明确提供它?感谢。
答案 0 :(得分:4)
您可以使用std :: function(在C ++ 11中)或boost :: function来存储可调用对象(函数,仿函数)。它实现了类型擦除模式。
class C {
public:
template <typename Func>
void foo(Func fun) {
_myFunc = fun;
}
void someOtherThing() {
_myFunc();
}
private:
std::function<void()> _myFunc;
};
答案 1 :(得分:-1)
这是一种避免使类C
成为模板的手工制作方式:
struct C {
template <typename Func>
void foo(Func fun) {
_myFunc = static_cast <void*>(&fun);
stub = call <Func>;
}
void someOtherThing() {
stub(_myFunc);
}
private:
void* _myFunc;
void (*stub)(void*);
template <typename F>
static void call(void* f) {
(*static_cast <F*>(f))();
}
};
struct S {
void operator()() { std::cout << "in S" << std::endl; }
};
int main()
{
S s;
C myClass;
myClass.foo(s);
myClass.someOtherThing();
}
当您致电foo()
时,在模板静态函数Func
中“存储”call
,这是指向stub
存储的指针(实例) 。后者由someOtherThing
调用以实际调用_myFunc
,这只是普通的void*
。为此,首先将_myFunc
强制转换回正确的类型,该类型仅在call
的正文中已知。
唯一的问题是使用指向函数的指针,stub(...)
调用没有内联。