我想做以下事情:
Example(&Class::MemberFunction, this));
//...
template<class T_CLASS>
inline static void Example(void (T_CLASS::*MemberFunctionPointer)(), T_CLASS* InstancePointer)
{
SomeClass<T_CLASS>::Bind<MemberFunctionPointer>(InstancePointer);
}
但我收到错误:*模板参数'T_MEMBER_FUNCTION':'MemberFunctionPointer':局部变量不能用作非类型参数*
针对此问题的任何解决方案?我想提供一种更简单的方式来调用“Bind”
谢谢,Mirco
//编辑:
我希望MemberFunctionPointer成为非类型模板参数,因为在“Bind”中我再次需要它作为模板参数。 正如您在答案中所写,在我的情况下,MemberFunctionPointer是一个变量,它的值在编译时是未知的。但是MemberFunctionPointer总是指向同一个函数。有没有办法让它保持不变,以便编译器在编译时知道它?
答案 0 :(得分:4)
模板参数有两种类型:类型和编译时常量表达式。函数参数的内容不是编译时可确定的值。因此,编译器无法基于它实例化模板。
请记住:模板是类型。并且类型必须在编译时可以确定。
您可能应该将成员指针作为参数传递给Bind
函数。
答案 1 :(得分:1)
我不太确定你想要达到的目标?
如果MemberFunctionPointer
是变量,那么编译时的值是未知的,例如,可能取决于某些用户行为 - 那么它就不能用作模板参数。
另一方面,如果MemberFunctionPointer
可以在编译时实际推断出,则应将其作为模板参数而不是函数参数传递。请考虑以下示例:
(在第一种情况下使用Bind
和call
;在第二种情况下,使用StaticBind
和callStatic
)
#include <stdio.h>
class X {
public:
int x;
void foo() {printf("foo\n");}
void bar() {printf("bar\n");}
};
template <typename T>
class SomeClass {
public:
static void Bind(void (T::*MemberFunctionPointer)(), T *obj) {
(obj->*MemberFunctionPointer)();
}
template <void (T::*MemberFunctionPointer)()>
static void StaticBind(T *obj) {
(obj->*MemberFunctionPointer)();
}
};
template <class C>
static inline void call(void (C::*MemberFunctionPointer)(), C *obj) {
SomeClass<C>::Bind(MemberFunctionPointer,obj);
}
template <class C, void (C::*MemberFunctionPointer)()>
static inline void callStatic(C *obj) {
SomeClass<C>::template StaticBind<MemberFunctionPointer>(obj);
}
int main() {
X obj;
call<X>(&X::foo,&obj);
callStatic<X,&X::bar>(&obj);
return 0;
}
答案 2 :(得分:1)
模板参数必须在编译时知道。作为函数参数的指针变量的内容取决于如何调用此函数。这在编译时是不知道的!
如果您已经在编译时知道此指针,则可以将函数指针运行时参数转换为模板参数:
template<class T_CLASS, void(T_CLASS::*MemFunPtr)()>
void Example(T_CLASS* InstancePointer) {...}
这里,MemFunPtr是一个在编译时已知的模板参数,因此可以作为另一个函数或类模板的模板参数重新使用...
答案 3 :(得分:0)
MemberFunctionPointer
是一个变量而不是类型(或编译时常量),因此无法使用,你需要的是该函数的真实签名,这样的事情可能是更好..
template<typename T_FUNC_PTR, class T_CLASS>
inline static void Example(T_FUNC_PTR fPtr, T_CLASS* InstancePointer)
{
SomeClass<T_CLASS>::Bind<T_FUNC_PTR>(fPtr, InstancePointer);
}
即。让编译器推导出函数指针的类型(注意:你也必须传播指向函数的指针),调用
Example(&foo::bar, foo_inst);
这是未经测试的,并且不在我的脑海中,所以语法可能稍微偏离......
编辑:这是一个更简单的例子来演示这个概念:
#include <iostream>
struct foo
{
void bar() { std::cout << "foo::bar()" << std::endl; }
};
template<typename T_FUNC_PTR, typename T_CLASS>
void exec(T_FUNC_PTR ptr, T_CLASS& inst)
{
(inst.*ptr)();
}
int main(void)
{
foo inst;
exec(&foo::bar, inst);
}