C 11中的右值和右值引用

2021-08-26 17:56:04 字數 1411 閱讀 2458

左值和右值:

1. 對乙個物件被用作右值的時候,用的是物件的值(內容);當物件被用作左值的時候,用的是物件的身份(在記憶體中的位置)。

2.  左值具有持久的狀態,而右值要麼是字面常量(注意字串常量是左值),要麼是在表示式求值過程中建立的臨時物件。

3.  返回左值引用的函式、賦值、下標、解引用、前置遞增/遞減運算子都是返回左值的表示式。(對於前置遞增/遞減如++a,是將持久物件a加1,然後返回持久物件a本身,所以是左值)

返回非引用型別的函式、算術、關係、位以及後置遞增/遞減運算子,都生成右值。(對於後置遞增或遞減如a++,是先取出持久物件a的乙份拷貝,再使持久物件a加1,最後返回那份拷貝,而這份拷貝使臨時物件,因此是右值)

4.簡單的來說,我們可以通過能不能對表示式取位址來判斷是左值還是右值。左值可以取位址,右值則不行。

右值引用:

1.右值引用只能繫結到乙個將要銷毀的物件。

2.當右值引用將該型別變數關聯到乙個將要銷毀的物件之後,那麼該物件的生命週期將和該變數一樣長。如int&& a = geta();函式geta()返回的臨時變數或物件的生命週期將和變數a一樣長。

3. 非常量左值引用、常量左值引用、非常量右值引用以及常量右值引用的初始化引用規則如下:

需要注意的是:對於   int && r1 = 13;是合法的,這是因為對於物件10,是字面常量;對於表示式10,是右值。

4. 要注意右值引用型別的變數本身是乙個左值,千萬不要將這個變數關聯到右值引用上。如

int && r1 = 42;  //正確,字面常量是右值

int && r2 = r1; //錯誤,表示式r1是左值

5. 在發生自動型別推導的時候(如函式模板或者auto關鍵字),t && t是乙個未定的引用型別(universal references)。如果是被乙個左值初始化,那麼 t 就是乙個左值。相反,如果是被乙個右值初始化,t 則是乙個右值。如下:

template

void f(t && t) 

//主函式

f(10);//傳入的是右值,因此t && 是右值引用型別,這一句不會報錯

int x = 10;

f(x);//傳入的是左值,因此t && 是左值引用型別,如果這句不注釋掉,編譯器會報錯,證明這條語句呼叫後的 t 是左值,而左值不能和右值引用關聯,所以報錯。

注意:上面的std::forward是用來保持引數的實際型別,即為了避免 t 本身是變數(左值),在進入函式體後根據實參初始化後 t 的屬性被本身左值屬性影響,即無論是用左值初始化還是右值初始化,由於t本身是左值導致在函式體內變成左值。使用std::forward就能保持初始化時的性質。

c 11 右值引用

右值引用 是一種復合型別,跟c 的傳統引用很類似。為更準確地區分兩種型別,我們把傳統的c 引用稱為 左值引用 而使用 引用 這一術語時,我們的意思同時包含兩種引用 左值引用和右值引用。右值引用的行為跟左值引用類似,不同之處在於 右值引用可以繫結到臨時量 右值 而 非const的 左值引用卻不能繫結到...

C 11 右值引用

消除兩個物件互動時不必要的物件拷貝,節省運算儲存資源,提高效率。能夠更簡潔明確地定義泛型函式。1.右值引用 int a a 1 here,a is an lvalue 上述的a就是乙個左值。c 11中左值的宣告符號為 為了和左值區分,右值的宣告符號為 printreference const str...

C 11右值引用

c 11中引入的乙個非常重要的概念就是右值引用。理解右值引用是學習 移動語義 move semantics 的基礎。而要理解右值引用,就必須先區分左值與右值。對左值和右值的乙個最常見的誤解是 等號左邊的就是左值,等號右邊的就是右值。左值和右值都是針對表示式而言的,左值是指表示式結束後依然存在的持久物...