Jun*_*eon 8 c++ templates member-functions
为什么成员函数不能用作模板参数?例如,我想这样做:
struct Foo {
void Bar() { // do something
}
};
template <typename TOwner, void(&func)()>
void Call(TOwner *p) {
p->func();
}
int main() {
Foo a;
Call<Foo, Foo::Bar>(&a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我知道使用指向成员的指针可以做类似的事情; 好吧,它大部分时间都很酷,但我只是好奇为什么指针"应该"使用.
我认为上面解释"p-> func()"没有含糊之处.为什么该标准禁止我们使用成员函数作为模板参数?根据我的编译器(VC++ 2013),甚至不允许使用静态成员函数.有谁知道原因?或者,有没有办法做同样的事情而不会因指针解除引用而失去任何性能?
谢谢.
use*_*267 24
它们可以用作非类型参数,但您需要使用正确的语法
struct Foo {
void Bar() { // do something
}
};
template <typename TOwner, void(TOwner::*func)()>
void Call(TOwner *p) {
(p->*func)();
}
int main() {
Foo a;
Call<Foo, &Foo::Bar>(&a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
事实上,成员函数指针可以用作模板参数(就像任何其他指针类型可以用作模板参数一样):
\n\nstruct A\n{\n int f(float x);\n};\n\ntemplate <int (A::F*)(float)>\nstruct B {};\n\ntemplate<A *> struct C;\ntemplate<A &> struct D;\nRun Code Online (Sandbox Code Playgroud)\n\n但是,根据以下 C++ 标准摘录,无法传递对成员的引用。
\n\n\n\n\n[温度参数]
\n\n\n
\n\n- 非类型模板参数应具有以下类型之一(可选 cv 限定):
\n(4.1) \xe2\x80\x94 整型或枚举类型,
\n\n(4.2) \xe2\x80\x94 指向对象的指针或指向函数的指针,
\n\n(4.3) \xe2\x80\x94 对对象的左值引用或对函数的左值引用,
\n\n(4.4) \xe2\x80\x94指向成员的指针,
\n\n(4.5) \xe2\x80\x94 std::nullptr_t。
\n
接下来,假设您设法以某种方式传递函数类型并希望在内部调用它,那么您会遇到与将它们存储在函数指针或对象内部std::function相同的问题:即调用您需要两者,还需要成员函数作为具体对象。仅传递函数是不够的。
但事实上你可以实现你想要的。只需将函数绑定到您的对象并随后传递它即可:
\n\ntemplate<typename T, typename F>\nvoid call(T&& t, F&&f)\n{\n f(std::forward<T>(t));\n}\n\nstruct A\n{\n void foo() { std::cout<<"hello"<<std::endl; } \n};\n\nint main()\n{\n A a;\n auto f=std::bind(&A::foo, a); //or possibly "std::ref(a)" instead of "a"\n call(3,f);\n}\nRun Code Online (Sandbox Code Playgroud)\n\n\n