C++11 引入右值引用,使我們能區分表達式的左值與右值,並將引用綁定到右值。語法使用雙 && 符號:
int&& rvalue_ref = 99; // 合法:綁定到右值字面量
注意:傳統左值引用(int&)不能綁定到右值:
int& ref = 9; // 錯誤:invalid initialization of non-const reference of type int& from an rvalue of type int
// 正確寫法:
int nine = 9;
int& ref = nine; // 綁定到左值
通過重載函數,可根據參數類型調用不同版本:
#include <iostream>
void f(int& i) { std::cout << "lvalue ref: " << i << std::endl; }
void f(int&& i) { std::cout << "rvalue ref: " << i << std::endl; }
int main() {
int i = 77;
f(i); // 調用 lvalue 版本
f(99); // 調用 rvalue 版本
f(std::move(i)); // 將左值轉為右值,調用 rvalue 版本
return 0;
}
若表達式結果是臨時對象,則為右值。例如函數按值返回:
#include <iostream>
int getValue() { int ii = 10; return ii; } // 返回臨時對象
int main() { std::cout << getValue(); return 0; } // getValue() 是右值
傳統 const int& 可綁定右值,但非 const 左值引用不可。C++11 右值引用允許非 const 綁定:
const int& val1 = getValue(); // OK
int& val2 = getValue(); // NOT OK
const int&& val3 = getValue(); // OK
int&& val4 = getValue(); // OK(C++11 新增)
通過右值引用重載,可實現移動構造/移動賦值,避免不必要的深拷貝。核心思想:「竊取」臨時對象的資源(如動態記憶體指針),而非複製。標準庫容器、智能指針、std::string 等均實現移動語義,大幅提升性能。
#include <iostream>
using namespace std;
void printReference(int& value) { cout << "lvalue: value = " << value << endl; }
void printReference(int&& value) { cout << "rvalue: value = " << value << endl; }
int getValue() { int temp_ii = 99; return temp_ii; }
int main() {
int ii = 11;
printReference(ii); // lvalue
printReference(getValue()); // rvalue
return 0;
}
/* 輸出:
lvalue: value = 11
rvalue: value = 99
*/
T&& 表示右值引用,綁定到臨時對象std::move() 將左值轉為右值引用,啟用移動語義ClassName(ClassName&& other)