2013-03-24 345 views
1

我有以下設置overlading參數推導:C++模板函數與常量參數

template <typename T> 
void foo(T& t); 
void foo(const int& t); 

void f() 
{ 
    int i; 
    foo(i); //Unresolved reference to "void foo<int>(int &)" 
    foo(const_cast<const int&>(i)); //Unresolved reference to "void foo(int const &)" 
} 

在第一次調用foo,那麼編譯器試圖調用模板版本,因爲非模板的參數一個不匹配的類型。在第二次調用中,調用非模板版本。我正在使用Microsoft C++編譯器版本10.此標準行爲?如果類型不完全匹配,即使它只有一個const修飾符,那麼模板函數被調用?

編輯:我知道這兩個函數沒有定義,我只是指出鏈接器抱怨什麼,以便更清楚編譯器想要調用什麼。

+3

「無法解析的參考」是鏈接器告訴你,你*聲明*某事,但從未*定義*它。 – 2013-03-24 16:38:53

+0

哪裏有功能模板的定義? – qPCR4vir 2013-03-24 16:40:45

回答

2

這是標準的行爲嗎?如果類型不完全匹配,即使它只有一個const修飾符,那麼模板函數被調用?

是的,這是由標準定義的。

如果沒有精確匹配,使用模板,因爲實例化模板版本總是比需要轉換一個更好比賽(甚至是它int &int const&轉換)。

-1

這應該工作

#include <iostream> 

template <typename T> 
void foo(T& t) {} 
void foo(const int& t){} 

void f() 
{ 
    int i; 
    foo(i); //Unresolved reference to "void foo<int>(int &)" 
    foo(const_cast<const int&>(i)); //Unresolved reference to "void foo(int const &); 
} 

int main() 
{ 
    f(); 
} 
+2

這不是問題。 – Nawaz 2013-03-24 16:44:25

4

,此行爲根據C++ 11標準是正確的。

在第一種情況下,參數是對非const整數的引用。這兩個重載都可以解決此調用,但函數模板允許完美匹配,而非模板過載需要進行資格轉換。

在第二種情況下,兩者完全匹配,但其中一個重載是而不是函數模板,因此它比函數模板更好。每§13.3.3/1,其實:

根據這些定義,一個可行函數F1被定義爲比另一種可行的功能 F2更好的功能,如果所有參數我,ICSI(F1)不低於ICSI(F2)更糟糕的轉換序列,然後

- 對一些參數Ĵ,ICSj(F1)比ICSj(F2)更好的轉換序列,或者,如果不說,

- 上下文是由用戶定義的轉換(參見8.5,13.3.1.5和13.3.1.6)和 標準轉換從F1的返回類型到目的地類型(即,被初始化的 實體的類型)的n序列是比從F235的返回類型到目的地類型的標準轉換序列更好的轉換序列。 [...]或者,如果不說,

- F1是一個非模板函數和F2是一個函數模板特,或者,如果不說,

- [...]