c11右值引用--筆記


C11中有左值引用和右值引用

 

左值引用

對一個變量的別名,不會調用拷貝構造,對別名的操作影響原值

eg:

 

 

運行結果:

 

 

 

右值引用

對匿名變量的引用,提出右值引用的原因:充分利用在函數調用過程中產生的臨時變量,對這個臨時變量達到最大限度的使用率

 

常用的匿名變量(對象):

 

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是一個偷盜//者更合適,它把那個臨時變量給偷過來了

 

注意:此處使用int並不是很明顯,如果使用一個T,T中包含指針數組,大家可能更容易明白

 

 

上面的c和d是程序員用戶自己寫的,他不在乎過程中多一次拷貝就按c的方式寫;如果他是一個處女座的程序員,他可能更喜歡使用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<<str<<”\n”;

}

 

void print_(std::string&& str) {

       std::cout<<str<<”\n”;

}

 

void test() {

       std::string str(“Hello World!”);

       print_(str);                      //左值引用,后面str內容不變

       print_(std::move(str));          //轉為右值引用 ,表示str可以被移動,但是否移動看后面接口的選擇了,由於此處僅是調用一個接收右值引用傳遞的方法,

                                                   //並不會修改str,即並沒有進行move操作,所以調用完成后str內容不會發生改變

}

 

注意std::move的本質,它其實就是一個轉換函數,將給定的類型轉化為右值引用,而並不是真正地“移動”了資源.

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM