C 之右值引用

2021-08-20 19:33:26 字數 2463 閱讀 4675

c++11中的新概念,主要解決了移動語義和完美**

我們平常使用的引用都是指左值引用。

下面是乙個測試例子

void func ( int& i ) 

void func ( std::string& s )

void rvalue ()

反正上面是出了問題,我們先了解一下基礎知識在來回答上面的問題。

左值(lvalue)和右值(rvalue)是從c繼承過來的概念,在c++11之後,新標準基於這兩個概念新增了部分特徵(右值引用,用來解決移動和**語義)。

什麼是左值、右值?

通俗的將:=左邊的是左值,右邊的是右值。

lvalue和rvalue的字首怎麼理解,left和right?好吧,l表示location,r表示read。

location表示可以在記憶體中定址,可以被賦值,read表示可以直接知道值

什麼是臨時變數?

對於全域性變數、區域性變數,我們都清楚,那麼什麼是臨時變數,什麼時候出現。

怎麼交換兩個數?建乙個臨時變數和第乙個交換,兩個變數交換,臨時變數和第二個交換。sorry,這只是我們業務邏輯上的臨時變數,確切的說,只是我們建立的乙個區域性變數而已,那對於程式(或者說執行中的程式來說)什麼才是臨時變數?網上有位大神是這麼解釋的:編譯期由編譯器根據程式需要自動生成的,在執行期跑的時候是真實存在的,而主要發生在兩個地方:函式傳參發生型別轉換時、函式返回值時。

比如說函式呼叫時,我們傳乙個字面量過去;或者函式返回乙個字面量時;或是表示式中發生了型別轉換時。

總結一句話:

1. 左值:能對表示式取位址、或具名物件/變數。一般指表示式結束後依然存在的持久物件。

2. 右值:不能對表示式取位址,或匿名物件。一般指表示式結束就不再存在的臨時物件。

在c++中,臨時物件不能作為左值,但可以作為常量引用const &

看下面的

++i = 3;  // ok

i++ = 3; // error c2106: 「=」: 左運算元必須為左值

++i:i先自增1,++i之後還是指向i的物件

i++:先把i自增之後的值丟給乙個臨時變數,自己去玩泥巴去了,i++之後指向的是那個臨時變數。如果放在單條語句中,這兩個沒啥區別。

好了,現在看看上面出問題的地方func(1); 這個函式需要的是乙個左值,但是字面量丟過去,她也只能放在乙個臨時變數中,而這個臨時變數不能作為乙個左值存在,就出了問題。

怎樣解決?

void func ( int&& i ) 

或是用func ( const int& i )

&& 和 &一樣都是引用,&&是新標準弄出來的,稱為 右值引用。

一般由static_cast < t&& >(t)轉換操作轉換而來

也可以用標準庫提供的std::move()來將左值轉換成右值引用

t&& 這是乙個左值,只不過她的型別是右值引用,只能繫結右值

額外說一句:如果型別是t&& 且這個t型別無需推導即可確定,那麼這個變數稱為帶名右值引用;如果這個t型別需要推導,那麼這個變數稱為**型引用。

總結一下:

1、新標準為c++帶來了乙個新的左值型別:帶名右值引用;帶來了乙個新的右值型別:無名右值引用

2、左值引用(就是以前的引用)可以繫結左值,也可以繫結右值;右值引用只能繫結右值(新型右值型別(右值引用)、傳統右值型別(臨時物件))。

a a;

a&& b = static_cast< a&&>(a);

a&& c = std::move(a);

建立兩個無名引用,用來初始化兩個右值引用物件

a& d = a;

a& e = b;

左值引用可以繫結左值

const a& f = c;

const a& g = a();

const引用(若無特殊說明,引用二字都是指傳統的左值引用)還可以繫結臨時變數

a&& h = a();

右值引用也可以繫結臨時變數

如果過載存在const引用和右值引用,新標準規定右值引用引數繫結的函式優先順序高於const引用

void func (const

int& i )

void func ( int&& i )

void func ( std::string& s )

void rvalue ()

結果如下:

func(int& i) = 123

func(std::string& s) = hello

func(int&& i) = 1 // 雖然兩個過載都滿足,但是新標準規定右值引用繫結的優先順序高於const左值引用

func(int& i) = 123

func(int&& i) = 123

原文出處

C 11之 右值引用

最近在看cocos2dx的源 發現了乙個模板類有乙個奇怪的語法 inline refptr refptr other 剛開始一陣犯暈,乙個型別ref和乙個似乎是形參的other與操作會得出乙個什麼?顯然這種理解是錯誤的。還有一種含義是右值引用,表示形參是乙個右值。左值 右值 int a 0 a是乙個...

C 11 理解 三 之 右值引用

c 11 增加乙個新的非常數引用 reference 型別,稱作右值引用 r value reference 標記為t 右值引用所引用的臨時物件可以在該臨時物件被初始化之後做修改,這是為了允許 move 語義。c 03 效能上被長期被詬病的其中之一,就是其耗時且不必要的深度拷貝。深度拷貝會發生在當物...

c 11新特性之右值引用

c 11 增加了乙個新的型別,稱為右值引用 r value reference 標記為 t 在介紹右值引用型別之前先要了解什麼是左值和右值。左值是指表示式結束後依然存在的持久物件,右值是指表示式結束時就不再存在的臨時物件。乙個區分左值與右值的便捷方法是 看能不能對表示式取位址,如果能,則為左值,否則...