c11中有左值引用和右值引用
對乙個變數的別名,不會呼叫拷貝構造,對別名的操作影響原值
執行結果:
對匿名變數的引用,提出右值引用的原因:充分利用在函式呼叫過程中產生的臨時變數,對這個臨時變數達到最大限度的使用率
常用的匿名變數(物件):
fun(a a()); //此時生產了乙個臨時變數,且無名,這就是右值
int add(int a, int b)
return (a + b); //此時的(a+b)的結果就是乙個臨時變數,且無名,這就是右值
並不是變數自動就會變成右值引用,需要使用者按右值引用的方式定義介面、定義變數,才會觸發右值引用,舉個例子:
1)fun (a a) { //再怎麼傳也不會變成右值引用
//todo
如果使用者使用 fun(a()); //則就是呼叫乙個普通的函式
2)如果想使用右值引用就需要使用者按右值引用定義介面,才會呼叫到這個右值引用
fun(a&& a){
//todo
fun(a()); //這時編譯器發現你有定義相關介面,就會去呼叫右值引用的函式了
上面1)和2)說的都是呼叫函式中的形參問題,下面說說變數問題;
int a=2, b=3;
int c = add(a, b); //c就是再普通不過的乙個左值,add先產生乙個臨時變數然//後再將臨時變數賦值給c
int&& d = add(a, b); //d就是乙個右值,add過程中產生乙個臨時變數,d就是這//個臨時變數的乙個「引用」,加引號是因為說d是乙個偷盜//者更合適,它把那個臨時變數給偷過來了
上面說的都是最正常的情況,即只對匿名變數(物件)使用右值引用,但是我們總是喜歡知道了乙個規則後,就千方百計利用這個規則,比如下面這種使用場景:
void test(){
t t;
fun(std::move(t)); //將t轉換成了乙個右值引用
void fun(t& t); //左值引用
void fun(t&& t); //右值引用
舉乙個可能用到的場景:
void print_(std::string& str) {
std::cout
std::cout
std::string str(「hello world!」);
print_(str); //左值引用,後面str內容不變
print_(std::move(str)); //轉為右值引用 ,表示str可以被移動,但是否移動看後面介面的選擇了,由於此處僅是呼叫乙個接收右值引用傳遞的方法,
//並不會修改str,即並沒有進行move操作,所以呼叫完成後str內容不會發生改變
注意std::move的本質,它其實就是乙個轉換函式,將給定的型別轉化為右值引用,而並不是真正地「移動」了資源.
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 的基礎。而要理解右值引用,就必須先區分左值與右值。對左值和右值的乙個最常見的誤解是 等號左邊的就是左值,等號右邊的就是右值。左值和右值都是針對表示式而言的,左值是指表示式結束後依然存在的持久物...