繁体   English   中英

在具有相同签名的模板化功能和非模板化功能之间进行选择时,为什么没有歧义?

[英]Why no ambiguity when choosing between templated and non-templated functions with same signatures?

以下代码传递断言:

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段:

[...]给定这些定义,如果对于所有自变量iICSi(F1)转换顺序都不比ICSi(F2)差,则一个可行函数F1被定义为比另一个可行函数F2更好的函数,然后[ ...] F1是非模板函数, F2是函数模板专门化[...]

不应该这样,因为签名最终是相同的。 那么为什么在调用foo<int>()时没有歧义呢? 我想念什么?

您引用的文本比较密集; 您必须仔细阅读。 “如果对于所有自变量i ,ICSi(F1)的转换顺序都不比ICSi(F2) ,则F1优于F2” –在这里是对的,因为两个转换顺序相同,因此,两个转换顺序都不比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)的调用一样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM