Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;调用模板函数的方法无法调用重载方法_C++_Templates_Generics_Function Pointers_Overloading - Fatal编程技术网

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); 
}