右值引用可以使我們區分表達式的左值和右值。
C++11引入了右值引用的概念,使得我們把引用與右值進行綁定。使用兩個“取地址符號”:
~~~
int&& rvalue_ref = 99;
~~~
需要注意的是,只有左值可以付給引用,如:
~~~
int& ref = 9;
~~~
我們會得到這樣的錯誤: “invalid initialization of non-const reference of type int& from an rvalue of type int”
我們只能這樣做:
~~~
int nine = 9;
int& ref = nine;
~~~
看下面的例子,你會明白的:
~~~
#include <iostream>
void f(int& i) { std::cout << "lvalue ref: " << i << "\n"; }
void f(int&& i) { std::cout << "rvalue ref: " << i << "\n"; }
int main()
{
int i = 77;
f(i); // lvalue ref called
f(99); // rvalue ref called
f(std::move(i)); // 稍后介紹
return 0;
}
~~~
右值有更隱晦的,記住如果一個表達式的結果是一個暫時的對象,那么這個表達式就是右值,同樣看看代碼:
~~~
#include <iostream>
int getValue ()
{
int ii = 10;
return ii;
}
int main()
{
std::cout << getValue();
return 0;
}
~~~
這里需要注意的是 getValue() 是一個右值。
我們只能這樣做,必須要有const
~~~
const int& val = getValue(); // OK
int& val = getValue(); // NOT OK
~~~
但是C++11中的右值引用允許這樣做:
~~~
const int&& val = getValue(); // OK
int&& val = getValue(); // OK
~~~
現在做一個比較吧:
~~~
void printReference (const int& value)
{
cout << value;
}
void printReference (int&& value)
{
cout << value;
}
~~~
第一個printReference()可以接受參數為左值,也可以接受右值。?
而第二個printReference()只能接受右值引用作為參數。
In other words, by using the rvalue references, we can use function overloading to determine whether function parameters are lvalues or rvalues by having one overloaded function taking an lvalue reference and another taking an rvalue reference. In other words, C++11 introduces a new non-const reference type called an rvalue reference, identified by T&&. This refers to temporaries that are permitted to be modified after they are initialized, which is the cornerstone of move semantics.
~~~
#include <iostream>
using namespace std;
void printReference (int& value)
{
cout << "lvalue: value = " << value << endl;
}
void printReference (int&& value)
{
cout << "rvalue: value = " << value << endl;
}
int getValue ()
{
int temp_ii = 99;
return temp_ii;
}
int main()
{
int ii = 11;
printReference(ii);
printReference(getValue()); // printReference(99);
return 0;
}
/*----------------------
輸出
lvalue: value = 11
rvalue: value = 99
----------------------*/
~~~
- 前言
- 吐血整理C++11新特性
- C++11新特性之std::function
- c++11特性之正則表達式
- c++11特性之Lambda表達式
- c++11特性之override和final關鍵字
- c++11特性之std::thread--初識
- c++11特性之std::thread--初識二
- c++11特性之initializer_list
- c++11特性之std::thread--進階
- c++11特性之std::thread--進階二
- C++11新特性之 CALLBACKS
- C++11新特性之 std::array container
- C++11新特性之 nullptr
- C++11新特性之 rvalue Reference(右值引用)
- C++11新特性之 Move semantics(移動語義)
- C++11新特性之 default and delete specifiers
- C++11新特性之 Static assertions 和constructor delegation
- 開始使用C++11的幾個理由
- C++11新特性之 std::future and std::async