如果你有这个通用功能:
template<class type, class ret, class atype1, class atype2, class atype3>
ret call3(type *pClass, ret(type::* funcptr)(atype1, atype2, atype3), atype1 arg, atype2 arg2, atype3 arg3)
{
//do some stuff here
return (pClass->*funcptr)(arg, arg2, arg3);
}
你这样做:
class MyClass
{
public:
void test(int, int, int){};
void test(int, int){};
void test(int, int, const char *){}; //comment this line, and it works fine.
};
...
MyClass *a = new MyClass();
call3(a, &MyClass::test, 1, 2, 3);
g ++会说:
no matching function for call to `call3(MyClass*&, <unknown type>, int, int, int)'
有什么方法可以解决这个问题吗? (我的代码可能非常糟糕,因为我不擅长C ++。)
答案 0 :(得分:3)
您必须指定所需的三项测试中的哪一项。这可以通过演员来完成:
call3(a, static_cast<void (MyClass::*)(int, int, int)>(&MyClass::test), 1, 2, 3);
真的不是那么干净。给函数赋予不同的名称可能会更好。
答案 1 :(得分:3)
您可以明确指定要使用的模板。
call3<MyClass, void, int, int, int>( a, &MyClass::test, 1, 2, 3 );
如果重新排列模板参数的顺序,可以从参数中获取MyClass和void,因此需要重载时的调用将如下所示:
call3<int,int,int>( a, &MyClass::test, 1, 2, 3 )
请注意,当您实际上不需要显式重载解析时,它仍然可以
call3( a, &MyClass::otherfunction, 1,2,3 );
答案 2 :(得分:2)
原因是编译器有两个重载可供选择,每个重载都有三个参数。请注意,在参数推导过程中,编译器会从函数调用参数中推断出参与模板参数,并且不知不觉地查看参数/参数对。
只有在明确地查看每个参数/参数对确定模板参数时,参数推断才会成功。这意味着,在查看第二个参数/参数对时,它确实(并且不能)依赖于atype1,atype2和atype3都是'int'类型的事实,即使您将模板参数重新排列为
template<class type, class ret, class atype1, class atype2, class atype3>
ret call3(type *pClass, atype1 arg, atype2 arg2, atype3 arg3, ret(type::* funcptr)(atype1, atype2, atype3))
{
//do some stuff here
return (pClass->*funcptr)(arg, arg2, arg3);
}
以下是支持此标准的标准引用:
未推断的上下文是:
- 类型的嵌套名称说明符 是使用qualified-id指定的。
- 非类型模板参数或 数组绑定其中的子表达式 引用模板参数。
- A. 中使用的模板参数 函数参数的参数类型 它有一个默认参数 在呼叫中使用 论证推论正在进行中。
- A 函数参数为哪个参数 扣除不能做因为 关联函数参数是一个 函数或一组重载 函数(13.4),以及一个或多个 以下适用:
- 不止一个 函数匹配函数 参数类型(导致 模棱两可的扣除),或
- 没有功能 匹配函数参数类型, 或
- 提供的功能集 参数包含一个或多个 功能模板。
现在找到解决方案,
我认为唯一的解决方案是您必须明确指定模板参数,而不是依赖于模板参数推导。对模板参数进行一点重新安排将有助于
template<class atype1, class atype2, class atype3, class type, class ret>
ret call3(type *pClass, ret(type::* funcptr)(atype1, atype2, atype3), atype1 arg, atype2 arg2, atype3 arg3)
{
//do some stuff here
return (pClass->*funcptr)(arg, arg2, arg3);
}
int main(){
MyClass *a = new MyClass();
call3<int, int, int>(a, &MyClass::test, 1, 2, 3);
}
答案 3 :(得分:0)
编译器无法推断出返回参数类型。您必须明确指定call3
的模板参数。
答案 4 :(得分:0)
我认为这里的问题是编译器无法解析您所指的test
函数。
如果假设您有以下方法
void test(int, int, int);
void test(int, int, const char *);
现在,如果你像这样打电话给test
test(1, 2, 3);
3
可以隐式转换为const char *
。因此编译器无法在函数test
的两个重载之间解析,从而导致编译错误。
JoshD给出的解决方案应解决您的问题