看下面例子:
?test(0)調用的是函數是:
template<typename T>
void test(T&& t) {std::cout << "右值引用" << std::endl;
}
?test(n)調用的是函數是:
?
template<typename T>
void test(T& t) {std::cout << "左值引用" << std::endl;
}
也就是說 0?是右值, n?是左值,現在假設我要把 n變為右值引用 ,讓它調用test(T&& t)函數怎么做?
方案1:
?
方案2:
以下方法是錯誤的:
為什么?
這是因為?r1
,?r2
, 和?r3
?本身都是左值,盡管它們被聲明為右值引用(int&&
)。
原因分析:
-
右值引用變量是左值:
雖然?r1
,?r2
,?r3
?的類型是?int&&
(右值引用),但它們本身是具名的變量,因此是左值。在 C++ 中,所有的具名變量都是左值,即使它們的類型是右值引用。 -
函數重載解析規則:
-
test(T& t)
?接受一個左值引用,可以綁定到左值(如?r1
,?r2
,?r3
)。 -
test(T&& t)
?是一個轉發引用(universal reference),但它只能綁定到右值(如臨時對象或?std::move(x)
?的結果)。由于?r1
,?r2
,?r3
?是左值,所以不會匹配這個版本。
-
法則1:在 C++ 中,所有的具名變量都是左值,即使它們的類型是右值引用。