1. 程式人生 > >C++11的右值引用(一)——左值(lvalue),純右值(prvalue)和將亡值(xvalue)

C++11的右值引用(一)——左值(lvalue),純右值(prvalue)和將亡值(xvalue)

基本概念

C++11之前只有左值和右值的概念:lvalue,rvalue。左值可以取地址,右值不能取地址。
但是C++11之後又劃分的更加詳細了,分為左值(lvalue),純右值(prvalue)還有將亡值(xvalue),關係如下:
這裡寫圖片描述
之前是lvalue的地方還是lvalue,之前是rvalue的地方變成了prvalue,而xvalue則是新加入的

  • lvalue:左值,即傳統意義上的左值。
  • xvalue(expiring value):x值(中間值?),指通過“右值引用”產生的物件。這裡x可以理解為即將消失(expiring),也可理解為中間(橫跨左值和右值)。
  • prvalue(pure rvalue):純右值,即傳統意義上的右值。

prvalue(pure rvalue):純右值,即傳統意義上的右值。
兩種複合型別:
glvalue(general lvalue):泛左值,由左值和x值構成。泛左值具有動態的型別和物件屬性。
rvalue:右值,由x值和純右值構成。右值具有潛在的可移動性。
關於右值引用:

  • 具名右值引用被視為左值。
  • 無名右值引用被視為x值。
  • 對函式的右值引用無論具名與否都將被視為左值。

    1. 把右值引用型別作為返回的函式或者過載操作符。例如, std::move(x);
    2. a[n], 內建的下標[subscript]表示式,其中,‘a’是一個右值陣列。
    3. a.m, 物件的取成員變量表達式。其中,‘a’是一個右值,‘m’ 是非引用型別的非靜態資料成員。
    4. a.*mp, 物件的成員指標表示式[the pointer to member of object expression]。其中,‘a’是右值,‘mp’是指向資料成員的指標。

lvalue+xvalue構成了glvalue(泛左值)都是有「身份」的值
prvalue+xvalue構成了rvalue(右值)都能被「移動」,右值都不能被取地址【至於什麼是移動(move)下篇帖子再講吧】

一個需要注意的地方

作為函式引數[argument],如果有兩個過載函式可用[avaliable],其中一個把右值引用作為引數[parameter],另一個把常左值引用作為引數,那麼右值會繫結[bind to]那個把右值引用作為引數的過載函式。(因此,在拷貝建構函式和移動建構函式都可用[available]的情況下,右值引數會呼叫[invoke]移動建構函式,拷貝賦值符號和移動賦值符號與之類似。)

記得移動建構函式的試用條件嗎,好好把上面這句話看一下。
另外關於移動建構函式,還有一句話就是:如果沒有顯示定義移動建構函式,但是顯示的定義了複製建構函式,那麼移動建構函式就不存在了

參考資料