在c++11中所有的值必屬於左值、右值兩者之一,右值又可以細分為純右值、將亡值。在c++11中可以取位址的、有名字的就是左值,反之,不能取位址的、沒有名字的就是右值(將亡值或純右值)。舉個例子,int a = b+c, a 就是左值,其有變數名為a,通過&a可以獲取該變數的位址;表示式b+c、函式int func()的返回值是右值,在其被賦值給某一變數前,我們不能通過變數名找到它,&(b+c)這樣的操作則不會通過編譯。
在理解c++11的右值前,先看看c++98中右值的概念:c++98中右值是純右值,純右值指的是臨時變數值、不跟物件關聯的字面量值。臨時變數指的是非引用返回的函式返回值、表示式等,例如函式int func()的返回值,表示式a+b;不跟物件關聯的字面量值,例如true,2,」c」等。
c++11對c++98中的右值進行了擴充。在c++11中右值又分為純右值(prvalue,pure rvalue)和將亡值(xvalue,expiring value)。其中純右值的概念等同於我們在c++98標準中右值的概念,指的是臨時變數和不跟物件關聯的字面量值;將亡值則是c++11新增的跟右值引用相關的表示式,這樣表示式通常是將要被移動的物件(移為他用),比如返回右值引用t&&的函式返回值、std::move的返回值,或者轉換為t&&的型別轉換函式的返回值。
將亡值可以理解為通過「盜取」其他變數記憶體空間的方式獲取到的值。在確保其他變數不再被使用、或即將被銷毀時,通過「盜取」的方式可以避免記憶體空間的釋放和分配,能夠延長變數值的生命期。
左值引用就是對乙個左值進行引用的型別。右值引用就是對乙個右值進行引用的型別,事實上,由於右值通常不具有名字,我們也只能通過引用的方式找到它的存在。
右值引用和左值引用都是屬於引用型別。無論是宣告乙個左值引用還是右值引用,都必須立即進行初始化。而其原因可以理解為是引用型別本身自己並不擁有所繫結物件的記憶體,只是該物件的乙個別名。左值引用是具名變數值的別名,而右值引用則是不具名(匿名)變數的別名。
左值引用通常也不能繫結到右值,但常量左值引用是個「萬能」的引用型別。它可以接受非常量左值、常量左值、右值對其進行初始化。不過常量左值所引用的右值在它的「餘生」中只能是唯讀的。相對地,非常量左值只能接受非常量左值對其進行初始化。
int &a = 2; # 左值引用繫結到右值,編譯失敗右值值引用通常不能繫結到任何的左值,要想繫結乙個左值到右值引用,通常需要std::move()將左值強制轉換為右值,例如:int b = 2; # 非常量左值
const int &c = b; # 常量左值引用繫結到非常量左值,編譯通過
const int d = 2; # 常量左值
const int &e = c; # 常量左值引用繫結到常量左值,編譯通過
const int &b =2; # 常量左值引用繫結到右值,程式設計通過
int a;int &&r1 = c; # 編譯失敗
int &&r2 = std::move(a); # 編譯通過
C 左值和右值,左值引用和右值引用
c 對於左值和右值沒有標準定義,但是有乙個被廣泛認同的說法 可見立即數,函式返回的值等都是右值 而非匿名物件 包括變數 函式返回的引用,const物件等都是左值。從本質上理解,建立和銷毀由編譯器幕後控制,程式設計師只能確保在本行 有效的,就是右值 包括立即數 而使用者建立的,通過作用域規則可知其生存...
C 左值和右值
c 左值與右值概念 變數和文字常量都有儲存區,並且有相關的型別,區別在於變數是可定址的 1 資料值,儲存在某個記憶體位址中,也稱右值 rvalue 右值是被讀取的值 read value 文字常量和變數都可被用於右值。2 位址值,即儲存資料值的那塊記憶體位址,也稱左值 lvalue 文字常量不能被用...
C 左值和右值
左值 lvalue 和右值 rvalue 是 c c 中乙個比較晦澀基礎的概念,有的人可能甚至沒有聽過,但這個概念到了 c 11 後卻變得十分重要,它們是理解 move,forward 等新語義的基礎。左值與右值這兩概念是從 c 中傳承而來的,在 c 中,左值指的是既能夠出現在等號左邊也能出現在等號...