對於這個代碼(可在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
左值中傳遞的第一個模板首選?
如何'T常量&'不匹配任何'T &&'可以嗎?有一個例子嗎? (我認爲它實際上*可以匹配任何東西,但是對於某些東西需要進行資格調整,比如非常量左值和右值。另外,對於右值,'T &&'優於'T const&',所以就是這樣。 – Xeo
@Xeo例如,'T const的&'不能推斷'INT&'或'INT &&'。如果你試圖用'int&'參數調用'f',f(const T&)'重載專用於'f(const int&)' - 特別是不是'f(int&)',並且需要一個轉換序列' int&' - >'const int&'。 – Casey
我取代「匹配」與「被推斷爲」中答覆,認爲這是更清晰一點。 – Casey