std::move()源碼分析

C++11 引入右值和移動語義,其中std::move()是不可或缺的。現在我們纔看看std::move()是這麼實現的。

remove_reference

在分析std::move()之前,先看看remove_reference,下面是remove_reference的實現:

template <class T>
struct remove_reference {
    using type = T;
};

// 特化版本
template <class T>
struct remove_reference<T&> {
    using type = T;
};

template <class T>
struct remove_reference<T&&> {
    using type = T;
};

remove_reference的作用是去除T中的引用部分,只獲取其中的類型部分。無論T是左值還是右值,最後只獲取它的類型部分。

std::move() 實現

藉助remove_referencestd::move()的實現如下:

template <class T>
typename tinySTL::remove_reference<T>::type&& move(T&& t) noexcept {
        using return_type = typename tinySTL::remove_reference<T>::type&&;
        return static_cast<return_type>(t);
    }

在這段實現看來,實際上std::move並沒有做什麼工作,只是做了類型轉換,將t轉化爲右值。

t 爲右值

t爲右值時,甚至都可以不用做類型轉換,直接返回即可。

t 爲左值

t爲左值的時候,可以作爲參數傳進std::move()嗎?可以的,這裏用到的技術是引用摺疊。
引用摺疊的規則可以概括爲:

  • X& &、X& && 和 X&& & 摺疊成 X&;
  • X&& && 摺疊成 X&&。

所以,當t爲左值或者左值引用時,進過引用摺疊,得到的類型是T&。最後就是將左值轉換爲右值並返回了。

總結

實際上,std::move()並不會move,僅僅做了類型轉換而已。真正的移動操作是在移動構造函數或者移動賦值操作符中發生的。
std::move()可以應用於左值,但這麼做要謹慎。因爲一旦“移動”了左值,就表示當前的值不再需要了,如果後續使用了該值,產生的行爲是未定義。

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章