以下代码传递断言:
int foo() { return 1; }
template<typename T>
int foo() { return 2; }
int main() {
assert( 1 == foo() );
assert( 2 == foo<int>() );
return 0;
}
但据我了解,根据 C++11 标准的第 13.3.3/1 段:
[...] Given these definitions, a viable function
F1
is defined to be a better function than another viable functionF2
if for all argumentsi
,ICSi(F1)
is not a worse conversion sequence thanICSi(F2)
, and then [...]F1
is a non-template function andF2
is a function template specialization [...]
不应该,因为签名最终是相同的。那么为什么foo<int>()
时没有歧义呢?叫做?我错过了什么?
最佳答案
你引用的文字比较密集;你必须仔细阅读它。 “如果对于所有参数 i
,ICSi(F1) 不是比 ICSi(F2) 更差的转换序列,则 F1 优于 F2”——这里是正确的,因为两个转换序列是相同,因此,两者都不比另一个差。所以现在你转到最后一部分:“然后 F1 是一个非模板函数,F2 是一个函数模板特化”。没错,所以 F1 比 F2 更匹配。替换 foo()
和 foo<int>()
对于 F1 和 F2,规则分别表示 foo()
是比 foo<int>()
更好的匹配.
糟糕,我回答错了问题。正如评论所指出的,问题是,为什么显式调用 foo<int>()
不解决 foo()
?答案是foo<int>()
是对显式模板实例化的调用,而不是对重载函数的调用。考虑:
template <class Ty>
void f(Ty) { }
void f(int);
void g(int);
f(3.14); // calls f<double> (overloaded function call)
f(1); // calls f(int) (overloaded function call)
f<int>(3.14); // calls f<int> (explicit call of template instantiation)
g(3.14); // calls g(int)
在这个例子中,f<int>
是模板特化的名称。它不是名为f
的通用函数,因此无需考虑重载,就像对 g(3.14)
的调用一样.
关于c++ - 为什么在具有相同签名的模板和非模板函数之间进行选择时没有歧义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54671044/