右值引用

1 什么是右值引用

int a = 4;

這里面a是左值,4是右值,一般的引用都只能設(shè)置為左值的引用

int& b = a;

b就是一個(gè)左值引用變量,意思為定義一個(gè)變量,綁定一個(gè)左值。顧名思義,右值引用的意思就是定義一個(gè)變量,綁定一個(gè)右值,cpp11里面的定義如下:

int&& a = 4;
如果定義:
int& a = 4;
會(huì)報(bào)錯(cuò):Non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'

立即數(shù),函數(shù)返回的值等都是右值。

2 移動(dòng)語意

右值引用的引入帶來的兩個(gè)好處,移動(dòng)語意和完美轉(zhuǎn)發(fā)。移動(dòng)語意可以在某些情況下節(jié)省拷貝次數(shù):舉例:

vector<int> v1 = {1,2,3};
vector<int> v2 = v1;

v2 = v1這個(gè)操作做了如下幾個(gè)操作, 構(gòu)造v2,之后將v1的所有元素拷貝到v2,如果我們不想繼續(xù)使用v1了,還需把v1銷毀。在cpp11中,可以直接使用如下做法:

vector<int> v1 = {1,2,3};
vector<int> v2 = vector(std::move(v1));
// 這個(gè)操作會(huì)同時(shí)給v2賦值,并且清空v1,這個(gè)其實(shí)是調(diào)用了v2的移動(dòng)構(gòu)造函數(shù)

標(biāo)準(zhǔn)庫源代碼如下:

/// Move constructor with alternative allocator
vector(vector&& __rv, const allocator_type& __m)
      noexcept(_Alloc_traits::_S_always_equal())
      : _Base(std::move(__rv), __m)
      {
    if (__rv.get_allocator() != __m)
      {
        this->_M_impl._M_finish =
          std::__uninitialized_move_a(__rv.begin(), __rv.end(),
                      this->_M_impl._M_start,
                      _M_get_Tp_allocator());
        __rv.clear();
      }
      }
// 最后會(huì)將右值引用入?yún)lear

右值引用也有延長(zhǎng)生命周期的作用。

3 通用引用

編譯器允許使用 A&& a的傳參方式去傳遞一個(gè)左值的引用,使用的方法是通過模板編程實(shí)現(xiàn)的:T&& 的作用主要是保持值類別進(jìn)行轉(zhuǎn)發(fā),參數(shù)既可以是左值引用,也可以是右值引用,所以也被叫做通用引用。具體做法是:

  • 判斷是左值還是右值。
  • 保留類型
  • 強(qiáng)制轉(zhuǎn)換為左值或者右值。

4 完美轉(zhuǎn)發(fā)

所謂的完美轉(zhuǎn)發(fā)就是,左值引用轉(zhuǎn)發(fā)后還是左值引用,右值引用轉(zhuǎn)發(fā)后還是右值引用。

std::forward();

什么情況下需要完美轉(zhuǎn)發(fā)呢:

但不是所有情況都這么簡(jiǎn)單。
比如像make_unique<T>(arg)這種泛型工具,
其中一步是以arg為參數(shù)調(diào)用T的構(gòu)造函數(shù)。
make_unique的作用就是避免用戶直接調(diào)用T的構(gòu)造函數(shù),
所以沒法讓調(diào)用方改成直接調(diào)用。
不知道T的構(gòu)造函數(shù)支持哪些 lvalue / rvalue 參數(shù),
所以必須按原樣轉(zhuǎn)發(fā),
不能全都當(dāng)作 lvalue 或者全都當(dāng)作 rvalue。
所以只能轉(zhuǎn)發(fā),而且必須是“完美”轉(zhuǎn)發(fā)。

作者:d41d8c
鏈接:https://www.zhihu.com/question/348291815/answer/839048206
來源:知乎
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

大意就是make_unique這種函數(shù),本身就是幫助你調(diào)用別人的構(gòu)造函數(shù),肯定只能是你想怎么調(diào),它就怎么調(diào),你是想傳左值引用還是右值引用,他都只能照辦,所以就有了完美轉(zhuǎn)發(fā)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容