c++11 左值引用和右值引用(std::move())

左值是表達式結束後依然存在的持久對象,既能出如今等號左邊也能出如今等號右邊的變量或表達式
右值是由於聲明結束後會被銷燬,因此不能放在等號左邊ios

#include <iostream>
using namespace std;


void Print(string& s){
    cout << s;
}


int main(){
    string s="abc";
    Print(s); // OK
    Print("abc"); // parse error
}

&是c++裏的左值引用
&&是c11裏的右值引用c++

  • 右值只能被const引用指向,在這時,右值的生命週期被延長了,直到引用銷燬。
  • 由於右值只能被const引用指向,因此咱們纔會在拷貝構造函數和賦值函數形參內加上const(還有一個緣由是避免參數被修改),這裏c11出現了一個特殊智能指針的non const拷貝構造函數
string Proc()
  {
       return string("abc");
  }
   
   int main()
  {
      const string& ref = Proc();
      //此時右值的生命週期延長了,直到main函數結束
      cout << ref << endl;
      return 0;
  }

 

使用std::move()接受一個參數,返回該參數對應的右值引用函數

template<typename _Tp>  
  inline typename std::remove_reference<_Tp>::type&&  move(_Tp&& __t)  
  { 
    return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); 
  }  
static_cast是一個強制類型轉換符,強制類型轉換會告訴編譯器:咱們知道而且不會在乎潛在的精度損失。
//下面有一個move使用的小例子
void swap(T& a, T& b)
 {
      T tmp = move(a);
      a = move(b);
      b = move(tmp);
      //能夠看出相比較以前的進行了屢次資源拷貝、銷燬的swap
      //在swap裏使用move只是進行了三次的指針交換,效率提高
 }

forward()接收一個參數,返回該參數原本所對應的類型的引用。(即完美轉發)spa

#include <iostream>
//#include <utility> //for std::forward
using namespace std;

void print(const int& t)
{
    cout <<"lvalue" << endl;
}

void print(int&& t)
{
    cout <<"rvalue" << endl;
}

template<typename T>
void Test(T&& v) //v是Universal引用
{
    //不完美轉發
    print(v);  //v具備變量,自己是左值,調用print(int& t)
    
    //完美轉發
    print(std::forward<T>(v)); //按v被初始化時的類型轉發(左值或右值)
    
    //強制將v轉爲右值
    print(std::move(v)); //將v強制轉爲右值,調用print(int&& t)
}

int main()
{
    cout <<"========Test(1)========" << endl; 
    Test(1); //傳入右值
    
    int x = 1;
    cout <<"========Test(x)========" << endl;
    Test(x); //傳入左值
    
    cout <<"=====Test(std::forward<int>(1)===" << endl;
    Test(std::forward<int>(1)); //T爲int,以右值方式轉發1
    //Test(std::forward<int&>(1)); //T爲int&,需轉入左值
    
    cout <<"=====Test(std::forward<int>(x))===" << endl;
    Test(std::forward<int>(x)); //T爲int,以右值方式轉發x
    cout <<"=====Test(std::forward<int&>(x))===" << endl;
    Test(std::forward<int&>(x)); //T爲int,以左值方式轉發x
    
    return 0;
}
/*輸出結果
e:\Study\C++11\16>g++ -std=c++11 test2.cpp
e:\Study\C++11\16>a.exe
========Test(1)========
lvalue
rvalue
rvalue
========Test(x)========
lvalue
lvalue
rvalue
=====Test(std::forward<int>(1)===
lvalue
rvalue
rvalue
=====Test(std::forward<int>(x))===
lvalue
rvalue
rvalue
=====Test(std::forward<int&>(x))===
lvalue
lvalue
rvalue
*/
相關文章
相關標籤/搜索