C 11的左值引用與右值引用總結

2021-08-20 16:49:50 字數 2010 閱讀 7197

概念

在c++11中,區別表示式是左值或右值可以做這樣的總結:當乙個物件被用作右值的時候,用的是物件的值(內容);當物件被用作左值的時候,用的是物件的身份(在記憶體中的位置)。左值有持久的狀態,而右值要麼是字面常量,要麼是在表示式求值過程中建立的物件,即左值持久,右值短暫

以上的定義來自於c++primer(5th)第121頁和第471頁。可能令人困惑,看了接下來的例子就明白了

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

int &&rr2 = rr1;//錯誤,表示式rr1是左值

特性中的應用

decltype關鍵字

使用關鍵字decltype的時候,左值和右值有所不同。如果表示式的求值結果是左值,decltype作用於該表示式(不是變數)得到乙個引用型別,例如,假定p的型別是int*,因為解引用運算子生成左值,所以decltype(*p)的結果是int&。另一方面,因為取位址運算子生成右值,所以decltype(&p)的結果是int**,也就是說,結果是乙個指向整型指標的指標。

lambda表示式

lambda表示式是形如auto f = [ ]的函式。

lambda可指定其捕獲列表的型別,[&]表示捕獲列表採用隱式引用捕獲方式lambda函式體中所使用的來自所在函式的實體都採用引用方式使用,[=]表示採用值捕獲方式。

/*f1的sz是隱式值捕獲,f2的sz是隱式引用捕獲

auto f1 = [=](const string &s)

auto f2 = [&](const string &s)

拷貝控制

移動建構函式使用右值引用的形參

class foo

;

引用摺疊和實參推斷

實參推斷,按照實參和形參匹配的規則。

引用摺疊:

通常情況下,我們不能將乙個右值引用繫結到乙個左值上,但是c++語言在正常繫結規則外定義了兩個例外規則,允許這種繫結。

第乙個例外規則影響右值引用的引數推斷如何進行:

當我們將乙個左值傳遞給函式的右值引用引數,且此右值引用指向模板型別引數(如t&&),編譯器推斷模板型別引數為實參的左值引用型別。

//編譯器推斷t型別是int&(左值引用),而非int

template void f(t&&);

int i = 0;

f(i);

引用摺疊:在所有情況下(除了乙個例外),引用會摺疊成乙個普通的左值引用型別。

即:對於乙個給定型別x

x& & ,x& && ,x&& &都摺疊成型別x&型別x&& &&摺疊成x&&

注:引用摺疊只能應用於間接建立的引用的引用,如型別別名或模板引數。

這兩個規則導致了兩個重要結果:

如果乙個函式引數是乙個指向模板型別引數的右值引用(如t&&),則他可以被繫結到乙個左值。且

如果實參是乙個左值,則推斷出的模板實參型別將是乙個左值引用,且函式引數將被例項化為乙個普通的左值引用引數(t&)

也暗示了:我們可以將任意型別的實參傳遞給t&&型別的函式引數。

函式過載

過載函式定義兩個版本,乙個版本接受乙個指向const的左值引用,第二個版本接受乙個指定非const的右值引用。即可接受所有可轉換成當前型別的物件

void foo(const x&);

void foo(x&&);

我們知道,非常量可以初始化乙個底層const,反過來卻不行,所以第一種版本可以接收任何能轉換成型別x的任何物件。第二種版本只可以傳遞非const右值,由於精確匹配規則,傳遞非const右值時,會呼叫第二種版本,儘管第一種版本也可以接受。

一般來說,我們不需要為函式操作定義接受乙個const x&&或是乙個普通的x&引數的版本。當我們希望從實參「竊取『資料時,通常傳遞乙個右值引用。為了達到這一目的,實參不能使const的。類似的,從乙個物件進行拷貝的操作,不應該改變該物件,因此,通常不需要定義乙個接受乙個普通的x&引數的版本。

C 11 左值引用與右值引用

在 c 11 的新標準中,出現了 右值引用 的說法,既然有了右值引用,那麼傳統的引用也就叫做左值引用。右值引用 rvalue referene 是 c 新標準 c 11,11 代表 2011 年 中引入的新特性 它實現了轉移語義 move sementics 和精確傳遞 perfect forwar...

C 11 左值引用與右值引用

左值,右值 英文並不是left value和right value,而是指記憶體儲存訪問的方式,左值有固定記憶體訪問位址 例如有名字的變數 右值沒有固定的記憶體訪問位址 例如函式的返回值 右值應用的作用 避免老的標準 現無謂的效能消耗,把無記憶體訪問的生命週期延長。在 c 11 的新標準中,出現了 ...

C 11 左值 右值 右值引用詳解

在c 11中所有的值必屬於左值 右值兩者之一,右值又可以細分為純右值 將亡值。在c 11中可以取位址的 有名字的就是左值,反之,不能取位址的 沒有名字的就是右值 將亡值或純右值 舉個例子,int a b c,a 就是左值,其有變數名為a,通過 a可以獲取該變數的位址 表示式b c 函式int fun...