2013-07-20 60 views
1

對於這個代碼(可在http://ideone.com/Mo7fQr爲什麼常量左值從給定T &&和const T&超載常量右值綁定不同?

template<typename T> 
void f(const T&) { std::cout << "const T& overload\n"; } 

template<typename T> 
void f(T&&) { std::cout << "T&& overload\n"; } 

int main() 
{ 
    const int x = 0; 

    f(x);     // calls const T& overload 
    f(std::move(x));  // calls T&& overload 
} 

第一次調用f(與左值)調用const T&過載,而第二呼叫(具有一個rvalue)調用T&&過載。至少gcc 4.8.1和最新的VC++(VC12)會發生這種情況。

我想我明白了爲什麼第二次呼叫解決,因爲它的作用:因爲第一個模板實例,以便在拍攝const int&參數,而第二個模板實例,以便在拍攝const int&&參數,因爲在調用點傳遞的參數是右值,它優先地綁定到右值引用。 (I相信這是在C++ 11標準在13.3.3.2/3子彈1子子彈4指明)

但對於第一次調用f,兩個模板實例採取const int&類型的參數。那麼,爲什麼當const左值中傳遞的第一個模板首選?

回答

1

當可以從多於一個的聲明來產生相同的功能模板專業化,聲明被使用的如在函數模板的C++ 11標準§14.5.6.2部分排序[描述函數模板部分排序消歧temp.func.order。編譯器確定哪些模板是最專業的並且更喜歡它。

在您的示例中,過載fT&&過載更專業。直觀地說,T&&可以推導出任何const T&可以,但不是反之亦然,因此const T&更爲具體,因此它的功能超載是更加專業化。

+0

如何'T常量&'不匹配任何'T &&'可以嗎?有一個例子嗎? (我認爲它實際上*可以匹配任何東西,但是對於某些東西需要進行資格調整,比如非常量左值和右值。另外,對於右值,'T &&'優於'T const&',所以就是這樣。 – Xeo

+0

@Xeo例如,'T const的&'不能推斷'INT&'或'INT &&'。如果你試圖用'int&'參數調用'f',f(const T&)'重載專用於'f(const int&)' - 特別是不是'f(int&)',並且需要一個轉換序列' int&' - >'const int&'。 – Casey

+0

我取代「匹配」與「被推斷爲」中答覆,認爲這是更清晰一點。 – Casey

相關問題