考虑下面的代码:
#include <iostream>
using namespace std;
class hello{
public:
void f(){
cout<<"f"<<endl;
}
virtual void ff(){
cout<<"ff"<<endl;
}
};
#define call_mem_fn(object, ptr) ((object).*(ptr))
template<R (C::*ptr_to_mem)(Args...)> void proxycall(C& obj){
cout<<"hello"<<endl;
call_mem_fn(obj, ptr_to_mem)();
}
int main(){
hello obj;
proxycall<&hello::f>(obj);
}
当然,在第16行编译时,这不会通过,因为编译器不知道R
,C
和Args
是什么。但还有另一个问题:如果在ptr_to_mem
之前尝试定义这些模板参数,就会遇到这种糟糕的情况:
template<typename R, typename C, typename... Args, R (C::*ptr_to_mem)(Args...)>
// ^variadic template, but not as last parameter!
void proxycall(C& obj){
cout<<"hello"<<endl;
call_mem_fn(obj, ptr_to_mem)();
}
int main(){
hello obj;
proxycall<void, hello, &hello::f>(obj);
}
令人惊讶的是,g++没有抱怨Args
不是模板列表中的最后一个参数,但无论如何它都不能将proxycall
绑定到正确的模板函数,并只是注意到它是一个可能的候选项。
有解决方法吗?我最后的办法是将成员函数指针作为参数传递,但如果我可以将其作为模板参数传递,它会更符合我的代码风格。
编辑:正如一些人所指出的那样,这个例子似乎毫无意义,因为proxycall
不会传递任何参数。但在我正在处理的实际代码中,参数是使用一些模板技巧从Lua堆栈中获取的。但是,这部分代码与问题无关,而且相当冗长,所以我不会在这里粘贴它。
proxycall()
不会向成员函数指针调用传递任何参数,因此使用变参模板参数似乎使问题变得比必要的更加困难。 - In silico<...>
显式指定。 - Luc Danton