[英]Function templates - compiler choosing function with different parameter types when calling with the same type
我正在玩功能模板,我偶然发现了一个奇怪的互动。
template<class T1, class T2>
void foo(T1, T1);
template<class T1, class T2>
void foo(T1, T2);
//main
foo(1,1)
这调用foo(T1,T2),我不明白为什么。 那会怎么样? 这些函数是否相互重载,为什么编译器会选择具有不同参数类型的函数?
Henri Menke的帖子的第一部分解释了这种特殊的互动
在经历了一些混乱后,我发现了一些更奇怪的东西
#include <iostream>
template<class T1, class T2>
void foo(T1 a, T1 b)
{
std::cout << "same\n";
}
template<class T1, class T2>
void foo(T1 a, T2 b)
{
std::cout << "different\n";
}
int main()
{
foo(1, 1);
foo<int, int>(1, 1);
}
在这段代码中我得到了一个结果
different
different
但在评论出第一个电话之后
int main()
{
//foo(1, 1);
foo<int, int>(1, 1);
}
结果是
same
我正在使用VS2015,如果我在Ideone中写同样的东西( 比如这里 ),第一个的结果是
different
same
有人能够解释发生了什么(或不发生了什么)?
顺便说一句,我得出的结论是调用foo<int, int>(1, 1);
应该是模棱两可的。 两个功能模板都具有相同的签名,并且来自同一模板。 那是另一回事,他们为什么不碰撞呢?
通过简单地删除第二个模板,即拥有类似的源文件,很容易看出为什么会失败
template<class T1, class T2>
void foo(T1, T1);
int main()
{
foo(1,1);
}
这在Clang中失败了
test.cpp:6:3: error: no matching function for call to 'foo'
foo(1,1);
^~~
test.cpp:2:6: note: candidate template ignored: couldn't infer template argument
'T2'
void foo(T1, T1);
^
1 error generated.
编译器无法推导出第二个模板参数T2
。
如果从第一个模板中删除多余的T2
并使用此类源文件
template<class T1>
void foo(T1, T1);
template<class T1, class T2>
void foo(T1, T2);
int main()
{
foo(1,1);
}
编译器将始终选择第一个选项(如果T1
和T2
当然是相同的),因为它更专业。
另一种选择是给T2
一个默认值。 然后第一个变体也可以从foo(1,1)
实例化。
template<class T1, class T2 = void>
void foo(T1, T1);
另一个有趣的事情是:
#include <iostream>
template<class T1, class T2>
void foo(T1, T1)
{ std::cout << "First choice!\n"; }
template<class T1, class T2>
void foo(T1, T2)
{ std::cout << "Second choice!\n"; }
int main()
{
foo<int,int>(1,1);
}
这将在运行时输出:
First choice!
我不完全确定,但我相信这是因为在演绎的情况下(即使这里没有执行),对于第一个变体,编译器必须只推导出一种类型而不是两种类型,这使得它更多专业选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.