C++ C++;调用模板函数的方法无法调用重载方法
如果您具有此通用功能:C++ C++;调用模板函数的方法无法调用重载方法,c++,templates,generics,function-pointers,overloading,C++,Templates,Generics,Function Pointers,Overloading,如果您具有此通用功能: 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->
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);
}
g++会说:
no matching function for call to `call3(MyClass*&, <unknown type>, int, int, int)'
调用'call3(MyClass*&,int,int,int)时没有匹配的函数
有办法解决这个问题吗?
(我的代码可能也非常糟糕,因为我不是很擅长C++)。< /P> < P>编译器不能推断返回参数类型。您必须明确指定
call3
的模板参数。您必须指定您需要的三个测试中的哪一个。这可以通过铸造来实现:
call3(a, static_cast<void (MyClass::*)(int, int, int)>(&MyClass::test), 1, 2, 3);
call3(一个静态类型转换(&MyClass::test),1,2,3);
其实并不是那么干净。给函数取不同的名称可能更好。我认为这里的问题是编译器无法解决您所指的
测试函数
假设你有以下方法
void test(int, int, int);
void test(int, int, const char *);
现在,如果您像这样调用test
test(1, 2, 3);
3
可以隐式转换为const char*
。因此,编译器将无法解决函数test
的两个重载之间的问题,从而导致编译错误
JoshD给出的解决方案应该可以解决您的问题您可以明确指定使用哪个模板
call3<MyClass, void, int, int, int>( a, &MyClass::test, 1, 2, 3 );
原因是编译器有两个重载可供选择,每个重载接受三个参数。请注意,在参数推导过程中,编译器会从函数调用参数中独立地推导参与模板参数,并查看参数/参数对
仅当模板参数通过查看每个参数/参数对明确确定时,参数推导才会成功。这意味着,在查看第二个参数/参数对时,它确实(也不能)依赖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);
}
模板
ret call3(类型*pClass,atype1 arg,atype2 arg2,atype3 arg3,ret(类型::*funcptr)(atype1,atype2,atype3))
{
//在这里做些事情
返回(pClass->*funcptr)(arg、arg2、arg3);
}
以下是支持该标准的引用:
非推断上下文为:
-
类型为的嵌套名称说明符
使用限定的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);
}
模板
ret call3(类型*pClass,ret(类型::*funcptr)(atype1、atype2、atype3)、atype1 arg、atype2arg2、atype3 arg3)
{
//在这里做些事情
返回(pClass->*funcptr)(arg、arg2、arg3);
}
int main(){
MyClass*a=新的MyClass();
call3(a,&MyClass::test,1,2,3);
}
当ret
绑定到void
时,它不抱怨void函数返回值吗?我没有抱怨。。。我不知道为什么。从返回void的函数返回void是有效的,纯粹是因为这种边缘情况在模板代码中更简单。@Alex:void函数中的return语句有一个表达式是完全可以的,只要该表达式的类型为void。@Alex Emelianov:参考3.9.1/9-“void类型的表达式只能用作表达式语句(6.2)、逗号表达式的操作数(5.18)、第二个或第三个操作数?:(5.16)、typeid的操作数,或者用作返回类型为void的函数的返回语句(6.6.3)中的表达式。”I get“无法声明指向void(&)(int,int,int)的指针。”
“@jcao219:可以,但这在参数推导方面有些复杂。请参阅我的response@jcao219:我有一个打字错误,删除演员阵容中的(&D)(答案经过编辑以反映这一点)。重新排序模板参数的那个似乎起了作用。谢谢!call3需要五个参数。您必须指定所有参数,因为没有默认参数。因此,添加MyClass
和void
。
call3( a, &MyClass::otherfunction, 1,2,3 );
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);
}
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);
}