| 類型 | 語法 | 標準 |
|---|---|---|
| 左值引用 | Type& attr(optional) declarator | C++98 |
| 右值引用 | Type&& attr(optional) declarator | C++11 |
Type&)左值引用是物件別名,必須初始化且不可重繫結。本質上為指標,編譯器自動處理取址與解引用。
std::string s = "Ex";
std::string& r1 = s;
const std::string& r2 = s;
r1 += "ample"; // 修改 s
// r2 += "!"; // 錯誤:const 引用不可修改
void double_string(std::string& s) { s += s; }
std::string str = "Test";
double_string(str); // str 變為 "TestTest"
char& char_number(std::string& s, size_t n) { return s.at(n); }
char_number(str, 1) = 'a'; // 修改 str[1]
Type&&)右值引用區分左值與右值,支援移動語義,可將臨時物件資源「移動」而非複製,延長臨時物件生命週期。
std::move(x) 結果)。const Type& 也可綁定右值(延長生命週期),但不可修改。
std::string s1 = "Test";
std::string&& r1 = s1; // 錯誤:s1 為左值
const std::string& r2 = s1 + s1; // 正常:const 左值引用延長臨時物件生命週期
std::string&& r3 = s1 + s1; // 正常:右值引用延長臨時物件生命週期
r3 += "Test"; // 正常:可修改非 const 右值引用
void f(int& x) { cout << "lvalue ref\n"; }
void f(const int& x) { cout << "const lvalue ref\n"; }
void f(int&& x) { cout << "rvalue ref\n"; }
int i = 1; const int ci = 2;
f(i); // lvalue ref
f(ci); // const lvalue ref
f(3); // rvalue ref
f(std::move(i)); // rvalue ref
此機制支援移動建構子 T(T&&) 與移動指派 T& operator=(T&&),實現資源高效轉移。
const Type&)。
右值引用是 C++11 移動語義的基石:
Class(Class&& other) noexcept : ptr(other.ptr) { other.ptr = nullptr; } 掠奪資源,避免深度複製。template<class T> void wrapper(T&& arg) { func(std::forward<T>(arg)); } 保持實參值類別(左值/右值)傳遞給目標函數。std::move(x):將左值強制轉換為右值引用(static_cast<T&&>(x)),聲明「可被移動」。| 特性 | 左值引用 T& | 右值引用 T&& |
|---|---|---|
| 綁定對象 | 左值 | 右值(臨時物件、std::move 結果) |
| 可修改性 | 可修改(非 const) | 可修改(非 const) |
| 生命週期延長 | 否(const T& 可) | 是 |
| 核心用途 | 別名、輸出參數、避免拷貝 | 移動語義、完美轉發、資源掠奪 |
| 多載優先級 | 左值優先匹配 | 右值優先匹配 |