【发布时间】:2012-04-04 11:10:43
【问题描述】:
考虑这段代码:
#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()不会将任何参数传递给成员函数指针调用,因此使用可变参数模板参数似乎使问题变得比它需要的更困难。 -
这没有意义。您的“call_mem_fn”#define 实际上并没有提供参数。因此,如果 Args 不是空的,它将不起作用。那么您如何期望它实际发挥作用呢?
-
问题中的代码只是一个例子。实际代码将处理具有任意数量参数的函数,并且它们将从其他地方(即 Lua 堆栈)检索。获取参数的元编程胶水代码已经在工作,我不会在这里粘贴它,因为它很长。
-
我想试一试,但它认为我在中途的某个地方迷路了,所以如果它关闭,请忽略答案。
-
FTR 可变参数包不必最后声明,但只能推导出来,而不是由
<...>的用户明确指定。
标签: c++ c++11 function-pointers variadic-templates