Max*_*Max 21 c++ gcc templates clang
我一直在尝试编译一个项目(使用gcc/g ++很好),其中clang和compilation卡在模板调用上.我试图创建最简单的类似代码,显示相同的错误消息.这里是:
#include <vector>
#include <utility>
#include <iostream>
using namespace std;
int A( double in )
{
return 1;
}
int A( int in )
{
return 1;
}
template<class M, class T>
M test(T input, M (fun) (T) )
{
return fun( input );
}
int main( int argc, const char *argv[] )
{
cout << test( (int) 1, A ) << test( (double) 1.2, A ) << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
来自clang的错误(当然会出现两次):
error: no matching function for call to 'test'
candidate template ignored: couldn't infer template argument 'M'
Run Code Online (Sandbox Code Playgroud)
Gcc不抱怨.请注意M是返回类型,始终为"int".
有人知道哪个是对的,为什么?
谢谢
g ++错了.从C++ 11 [temp.deduct.type] p5:
非推导的上下文是:[...] - 无法进行参数推导的函数参数,因为关联的函数参数是一组重载函数,以及[...]多个函数匹配函数参数类型
这种确定是在不考虑可能在其他地方推断出的模板参数的情况下进行的,因此T必须推导出的事实int与此处无关.这使得整个参数M (fun)(T)成为非推导的上下文.因此M无法推断,正如Clang声称的那样.
在确定第二个参数是否是非推导的上下文时,g ++似乎错误地使用了第一个函数参数中的' T= int'推论.反转函数参数的顺序会导致g ++拒绝代码:
int A(double);
int A(int);
template<class M, class T>
M test(M (fun) (T), T input) {
return fun( input );
}
int main( int argc, const char *argv[]) {
test(A, 1);
test(A, 1.2);
}
Run Code Online (Sandbox Code Playgroud)
我之前的回答(现已删除)是错误的。叮当错了。
编译器应该能够推断出类型,M因为函数参数是M(fun)(T)。注意,函数指针参数列表中没有M,所以这对应于14.8.2.5中的T()(C++11)/ T(*)()(C++93):
其中
(T)表示参数类型列表,其中至少一个参数类型包含T,()表示参数类型列表,其中没有参数类型包含T。