T&&C++11 引入 T&& 作為獨立類型,區別於 T&(左值引用)。右值引用綁定到右值(臨時對象、將亡值、字面值)。
void f(T&) 匹配左值。void f(T&&) 匹配右值。void f(const T&) 匹配左值/右值(萬能引用)。若需將左值強制匹配右值引用參數,用 static_cast 或 std::move(x)。
為避免深拷貝開銷,類可定義移動構造 T(T&& other) 和移動賦值 T& operator=(T&& other),將資源(指針、句柄等)從 other 偷取過來,並將 other 置為空狀態。編譯器不會自動生成移動操作(若用戶聲明了析構/拷貝/移動/賦值中的任意一個),需用 =default 顯式要求生成或自行實現。
std::move(x) 等價於 static_cast,只是強制類型轉換,**不移動任何東西**。真正的移動發生在調用移動構造/賦值時。對已移動對象僅能安全析構或賦新值。
函數返回對象時,編譯器優先使用 RVO/NRVO(返回值優化),直接在調用者棧框構造,省去移動。若禁用 RVO(-fno-elide-constructors),則會調用移動構造。不要返回局部對象的引用(右值引用也不行),因局部對象生命周期結束。
右值引用只能用右值、字面值、將亡值、std::move 結果初始化。const T& 可綁定一切,是萬能引用。
若類聲明了析構、拷貝構造、拷貝賦值、移動構造、移動賦值中任意一個,編譯器**不再隱式生成**移動操作。需用 =default 讓編譯器生成默認移動(逐成員移動),或 =delete 禁用。
class Test {
unique_ptr<int> p;
public:
Test() : p(new int) {}
~Test() = default;
Test(const Test&) = delete;
Test& operator=(const Test&) = delete;
Test(Test&&) = default; // 默認移動構造
Test& operator=(Test&&) = default; // 默認移動賦值
};