![](/img/trans.png)
[英]Why is it illegal for non-templated functions to have same name and arguments but different return types? (but legal for template functions?)
[英]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段:
[...]給定這些定義,如果對於所有自變量
i
,ICSi(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.