當前位置: 華文星空 > 知識

C++中的std::move函數到底是做什麽的?

2021-06-25知識

沒有了。 move 就是做類別轉換的,把指代物件的左值運算式變成亡值。

move 單獨出現沒有意義,本身不會對物件做任何事。它可以有意義的場景是可能涉及函數呼叫的情況(如直接的函數呼叫、變量初始化、呼叫運算子等)。

此時它的意義是使外面的函數呼叫選擇接受右值的版本,實際的移動工作是由外面的函數進行的,物件不該使用的情況也是限於被該函數移動後,像題目裏描述的單純參照繫結與此無關。

可以認為這裏的「使用」指的是「任何依賴物件需要有某種符合期待的值」的操作(在不確定的值上呼叫這些操作可能始終合法,但也可能導致錯誤的業務邏輯),但不指對它賦值之類的「不依賴物件的舊值並只會使之擁有確定的新值」的操作。因為標準庫設計是大多數具備移動語意的類別被移動後處於合法但未指定的狀態。

有些人說到函數命名…

我們可以註意到 C++ 標準居里這些函數樣版照原樣返回參數所參照的物件,做的事情只有顯式轉型,如將它們從左值變成右值或者加上 const 限定(這些函數都是單獨出現時無意義,僅在涉及外面的操作時才有意義):

  • move
  • forward
  • move_if_noexcept
  • as_const
  • identity::operator() (此函數本身無直接使用的必要,主要用於 ranges 演算法的維持參數原狀的預設投影操作。)
  • 這裏 move move_if_noexcept 的名字所表示的並非它們本身的作用,而是「對外面的函數呼叫優先選擇的操作」。誠然,這種名稱設計給不少人帶來了誤解,也和後續命名風格不一致。

    (這些名字中 move 是最早定下來的,在 2002 年的提案 WG21-N1377 中就出現了。 move_if_noexcept 出現較晚,名字設計只是為了和 move 一致。)

    有人說到變量名…

    變量名作為運算式都是左值這點是值得記下來的。

    不過…其實上面那些函數都包含「擦掉變量名」的作用,而「是否作為變量名」有顯著影響的地方更多在於 decltype ,和這個問題大概關系不大?