首頁  >  文章  >  後端開發  >  當右邊值參考應該只綁定到右邊值時,std::move() 如何綁定到左值?

當右邊值參考應該只綁定到右邊值時,std::move() 如何綁定到左值?

DDD
DDD原創
2024-11-14 10:46:01964瀏覽

How does std::move() bind to lvalues when rvalue references are supposed to only bind to rvalues?

揭開std::move 轉換魔法的神秘面紗

當調用std::move() 時,令人費解的是觀察到引用的右值參數可以綁定到左值,通常限制左值附加到右值引用。深入研究 std::move() 的實現揭示了這個明顯悖論的關鍵。

剖析std::move() 實作

從精煉的開始std::move() 的版本:

template <typename T>
typename remove_reference<T>::type&& move(T&& arg) {
  return static_cast<typename remove_reference<T>::type&&>(arg);
}

案例1:呼叫move()與右值

當 move() 與右邊值一起使用時,例如暫時物件:

Object a = std::move(Object()); // Object() is temporary, hence prvalue

產生的範本實例化為:

remove_reference<Object>::type&& move(Object&& arg) {
  return static_cast<remove_reference<Object>::type&&>(arg);
}

由於remove_reference將T&轉換為T或T&&轉換為T,而Object是一個普通值,所以最終的函數形態變為:

Object&& move(Object&& arg) {
  return static_cast<Object&&>(arg);
}

強制轉換至關重要,因為命名的右值引用被視為左值。

情況2:使用左值呼叫move()

使用左值呼叫move() 時:

Object a; // a is an lvalue
Object b = std::move(a);

產生的move () 實例化為:

remove_reference<Object&>::type&& move(Object& && arg) {
  return static_cast<remove_reference<Object&>::type&&>(arg);
}

再,remove_reference將 Object& 轉換為 Object,產生:

Object&& move(Object& && arg) {
  return static_cast<Object&&>(arg);
}

引用摺疊的本質

理解 Object& && 與其綁定左值的能力是關鍵解開謎團。 C 11 引入了引用折疊的特殊規則,其中規定:

Object & && = Object &
Object & &&& = Object &
Object && & = Object &
Object && &&& = Object &&

因此,Object& && 實際上轉換為 Object&,一個可以輕鬆綁定到左值的典型左值引用。

結果函數

根據這些規則,最終函數變成:

Object&& move(Object& arg) {
  return static_cast<Object&&>(arg);
}

鏡像右值的實例化,它將其參數轉換為右值引用,從而確保統一的行為。

remove_reference 的重要性

當檢查替代方案時,remove_reference的目的就變得顯而易見函數:

template <typename T>
T&& wanna_be_move(T&& arg) {
  return static_cast<T&&>(arg);
}

當用左值實例化時:

Object& && wanna_be_move(Object& && arg) {
  return static_cast<Object& &&&>(arg);
}

應用引用折疊規則會顯示一個不可用的類似移動的函數,為左值參數傳回左值。罪魁禍首是缺少remove_reference,它阻礙了正確轉換為右值引用。

以上是當右邊值參考應該只綁定到右邊值時,std::move() 如何綁定到左值?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn