C++11 引入了右值引用與移動語義,徹底改變了資源管理方式。要理解 std::move、std::forward 等機制,必須先搞清楚左值與右值的本質。本文依據 C++ 標準草案(N3797)與 cppreference 等權威資料,系統梳理值類別體系。
C++ 表達式分為兩大基本類別:glvalue(廣義左值)與 rvalue(右值)。其中 glvalue 再細分為 lvalue(左值)與 xvalue(將亡值);rvalue 細分為 prvalue(純右值)與 xvalue。關係圖譜如下:
expression
├── glvalue (has identity)
│ ├── lvalue (cannot be moved from)
│ └── xvalue (can be moved from)
└── rvalue (can be moved from)
├── prvalue (no identity)
└── xvalue (has identity)
*p、返回左值引用的函數調用、前置遞增 ++i。i++、算術運算結果等。std::move(x) 的結果)。42、lambda 表達式、算術運算結果)。| 表達式 | 類別 | 說明 |
|---|---|---|
變量名 x | lvalue | 即使類型是右值引用,表達式本身仍是左值 |
std::move(x) | xvalue | 轉換為右值引用 |
42, true | prvalue | 字面值 |
x + y | prvalue | 算術運算結果 |
++x | lvalue | 前置遞增返回左值引用 |
x++ | prvalue | 後置遞增返回臨時值 |
*p | lvalue | 解引用指針 |
a[n] (a 為左值) | lvalue | 下標運算 |
a[n] (a 為右值) | xvalue | C++11 起 |
T&&,左值綁定 T& 或 const T&。std::move) 可觸發移動構造/賦值,避免深拷貝。std::forward 保持實參值類別。