首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

C++11 std::move 與 std::forward 源碼深度解析

     編輯:C++ 入門

C++11 std::move 與 std::forward 源碼深度解析

std::move 實現移動語義,std::forward 實現完美轉發。本文基於 GCC 4.6 標準庫源碼,逐行分析實現機制。

預備知識

  • 引用折疊:T& & → T&, T&& & → T&, T& && → T&, T&& && → T&&。
  • 模板參數推導(右值引用形參):
    • 實參為左值 U& → 推導 T = U&。
    • 實參為右值 U&& → 推導 T = U。
  • std::remove_reference:去除類型中的引用,remove_reference::type = T。
  • static_cast(expr):將表達式轉為類型 T 的右值(無名右值引用)。

std::move 實現

template
inline typename std::remove_reference<_Tp>::type&&
move(_Tp&& __t) {
    return static_cast::type&&>(__t);
}

左值調用分析 move(a)(a 為 X 類型左值)

  1. 形參 _Tp&& 匹配 X& → 推導 _Tp = X&。
  2. remove_reference::type = X。
  3. 返回類型 X&&。
  4. static_cast(a) 將左值 a 轉為右值。

右值調用分析 move(X())

  1. 形參匹配 X&& → 推導 _Tp = X。
  2. remove_reference::type = X。
  3. 返回類型 X&&。
  4. static_cast(X()) 右值保持右值。

std::forward 實現

// 重載 1:左值引用形參
template
inline _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);
}

完美轉發場景

template
void 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)

  1. outer 推導 T = X&,形參 t 類型 X&。
  2. 調用 forward(t)。
  3. 匹配重載 1:_Tp = X&,remove_reference::type = X,形參類型 X& 匹配。
  4. static_cast(t) → 引用折疊 X&,保持左值。

右值轉發分析 outer(X())

  1. outer 推導 T = X,形參 t 類型 X&&。
  2. 調用 forward(t)。
  3. 匹配重載 1:_Tp = X,形參類型 X& 不匹配 X&&。
  4. 匹配重載 2:_Tp = X,形參類型 X&& 匹配,靜態斷言通過。
  5. static_cast(t) 保持右值。

核心差異總結

工程應用建議

  • swap 實現:T tmp(move(a)); a = move(b); b = move(tmp);。
  • 工廠函數完美轉發構造參數:template unique_ptr make(Args&&... args) { return unique_ptr(new T(forward(args)...)); }。
  • 只有確定不再使用對象時才 move,轉發場景優先 forward。

深入理解這兩個工具的編譯期類型推導與引用折疊機制,是掌握 C++11 移動語義與完美轉發的核心鑰匙。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
特性std::movestd::forward
目的無條件轉右值條件保持值屬性
參數單參數模板參數 T + 函數參數
典型用途移動構造/賦值轉發給其他函數
實現關鍵remove_reference + cast雙重載 + 靜態斷言