std::move 實現移動語義,std::forward 實現完美轉發。本文基於 GCC 4.6 標準庫源碼,逐行分析實現機制。
T& & → T&, T&& & → T&, T& && → T&, T&& && → T&&。U& → 推導 T = U&。U&& → 推導 T = U。remove_reference::type = T 。T 的右值(無名右值引用)。templateinline typename std::remove_reference<_Tp>::type&& move(_Tp&& __t) { return static_cast ::type&&>(__t); }
move(a)(a 為 X 類型左值)_Tp&& 匹配 X& → 推導 _Tp = X&。remove_reference::type = X 。X&&。static_cast(a) 將左值 a 轉為右值。move(X())X&& → 推導 _Tp = X。remove_reference::type = X 。X&&。static_cast(X()) 右值保持右值。// 重載 1:左值引用形參 templateinline _Tp&& forward(typename std::remove_reference<_Tp>::type& __t) { return static_cast<_Tp&&>(__t); } // 重載 2:右值引用形參(含靜態斷言防誤用) template inline _Tp&& forward(typename std::remove_reference<_Tp>::type&& __t) { static_assert(!std::is_lvalue_reference<_Tp>::value, "template argument substituting _Tp is an lvalue reference type"); return static_cast<_Tp&&>(__t); }
templatevoid outer(T&& t) { inner(forward (t)); } void inner(const X&) { cout << "lvalue\n"; } void inner(X&&) { cout << "rvalue\n"; } int main() { X a; outer(a); // 輸出 lvalue outer(X()); // 輸出 rvalue }
outer(a)outer 推導 T = X&,形參 t 類型 X&。forward(t) 。_Tp = X&,remove_reference::type = X ,形參類型 X& 匹配。static_cast(t) → 引用折疊 X&,保持左值。outer(X())outer 推導 T = X,形參 t 類型 X&&。forward(t) 。_Tp = X,形參類型 X& 不匹配 X&&。_Tp = X,形參類型 X&& 匹配,靜態斷言通過。static_cast(t) 保持右值。| 特性 | std::move | std::forward |
|---|---|---|
| 目的 | 無條件轉右值 | 條件保持值屬性 |
| 參數 | 單參數 | 模板參數 T + 函數參數 |
| 典型用途 | 移動構造/賦值 | 轉發給其他函數 |
| 實現關鍵 | remove_reference + cast | 雙重載 + 靜態斷言 |