2013-02-02 87 views
18

我有這樣的代碼:爲什麼使用「相同簽名」的模板和非模板函數的重載稱爲非模板函數?

template< 
    class T = const int & 
> void f(T) {} 

void f(const int &) {} 

int main() { 
    f(0); 
} 

它爲什麼稱之爲第二個,而不是第一?我會認爲它們是相同的,但它們顯然不是,因爲我沒有得到重新定義的錯誤。

+2

http://stacked-crooked.com/view?id=f9aac9532f21077433027f9ae341417b此處呼叫號碼2。 – Rapptz

+0

@Rapptz是的,我編輯。 – user2030677

回答

19

因爲第二次重載不是模板。

當模板函數和非模板函數都可用於解析函數調用時,將選擇非模板函數。

從第13.3.3/C++的11標準的1:

[...]根據這些定義,一個可行的函數F1被定義爲一個更好功能比另一個可行函數F2如果對於所有參數i,ICSi(F1)不是比ICSi(F2)更差的轉換序列,則,然後F1是非模板函數,F2是功能模板專門化 [...]

+1

然後,也許作爲一個側面的問題,你可以回答爲什麼[它在這一個叫#2?](http://stacked-crooked.com/view?id=f9aac9532f21077433027f9ae341417b)這實際上只是導致問題也改變了。 – Rapptz

+0

@Rapptz:正是因爲#2不是模板。我錯過了什麼嗎? –

+0

閱讀理解有點偏離。 – Rapptz

6

一個是模板,另一個不是,他們是defin好像不一樣。

重載分辨率旨在優先選擇模板函數中的非模板,其他任何內容都相等。