Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.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++_Templates_Language Lawyer - Fatal编程技术网

C++ 为什么在选择具有相同签名的模板函数和非模板函数时没有歧义?

C++ 为什么在选择具有相同签名的模板函数和非模板函数时没有歧义?,c++,templates,language-lawyer,C++,Templates,Language Lawyer,以下代码传递断言: int foo() { return 1; } template<typename T> int foo() { return 2; } int main() { assert( 1 == foo() ); assert( 2 == foo<int>() ); return 0; } intfoo(){return 1;} 模板 int foo(){return 2;} int main(){ 断言(1==foo()); 断言(2==

以下代码传递断言:

int foo() { return 1; }

template<typename T>
int foo() { return 2; }

int main() {
  assert( 1 == foo() );
  assert( 2 == foo<int>() );
  return 0;
}
intfoo(){return 1;}
模板
int foo(){return 2;}
int main(){
断言(1==foo());
断言(2==foo());
返回0;
}
但据我所知,根据C++11标准第13.3.3/1段:

[…]根据这些定义,一个可行函数
F1
被定义为比另一个可行函数
F2
更好的函数,如果对于所有参数
i
ICSi(F1)
不是比
ICSi(F2)
更糟糕的转换序列,那么[…]
F1
是非模板函数,
F2
是函数模板专用化[…]


不应该这样,因为签名最终是相同的。那么为什么调用
foo()
时没有歧义呢?我错过了什么

你引用的文本相当密集;你必须仔细阅读。“F1优于F2,如果对于所有参数
i
,ICSi(F1)不是比ICSi(F2)更差的转换序列”--这里是这样,因为两个转换序列是相同的,因此,都不比另一个更差。现在转到最后一部分:“然后F1是非模板函数,F2是函数模板专用化”。这是真的,所以F1比F2更匹配。将F1和F2分别替换为
foo()
foo()
,规则表明
foo()
foo()
更匹配

哎呀,我回答错问题了。正如评论所指出的,问题是,为什么显式调用
foo()
不能解析为
foo()
?答案是,
foo()
是对显式模板实例化的调用,而不是对重载函数的调用。考虑:

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(Ty){}
无效f(int);
无效g(int);
f(3.14);//调用f(重载函数调用)
f(1);//调用f(int)(重载函数调用)
f(3.14);//调用f(模板实例化的显式调用)
g(3.14);//呼叫g(int)

在本例中,
f
是模板专门化的名称。一般的函数名为<代码> f>代码>,所以不需要考虑重载,就像调用<代码> g(3.14)< /代码> .< /p> < p>您所引用的文本相当密集;你必须仔细阅读。“F1优于F2,如果对于所有参数
i
,ICSi(F1)不是比ICSi(F2)更差的转换序列”--这里是这样,因为两个转换序列是相同的,因此,都不比另一个更差。现在转到最后一部分:“然后F1是非模板函数,F2是函数模板专用化”。这是真的,所以F1比F2更匹配。将F1和F2分别替换为
foo()
foo()
,规则表明
foo()
foo()
更匹配

哎呀,我回答错问题了。正如评论所指出的,问题是,为什么显式调用
foo()
不能解析为
foo()
?答案是,
foo()
是对显式模板实例化的调用,而不是对重载函数的调用。考虑:

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(Ty){}
无效f(int);
无效g(int);
f(3.14);//调用f(重载函数调用)
f(1);//调用f(int)(重载函数调用)
f(3.14);//调用f(模板实例化的显式调用)
g(3.14);//呼叫g(int)

在本例中,
f
是模板专门化的名称。一般的函数名为<代码> f>代码>,所以没有重载要考虑,就像调用<代码> g(3.14)< /代码> .< /p>我没有得到的是为什么调用fo < int >,因为它归结为与FoE()相同的签名。或者它们被认为是不同的?@z3dd是的,它们是不同的:
foo
是一个模板实例化。因此,它不能与非模板
foo
相同。不能通过提供模板参数引用非模板。我不明白为什么允许调用foo,因为它归结为与foo()相同的签名?或者它们被认为是不同的?@z3dd是的,它们是不同的:
foo
是一个模板实例化。因此,它不能与非模板
foo
相同。不能通过提供模板参数引用非模板。所以没有歧义。