c++标准库

右值引用

为了解决不必要的复制,并且允许perfect forwarding;

当赋值操作(=号)的右边是一个右值rvalue,那么左边的对象可以从右边的对象“偷”resources,即允许move语义;

Lvalue: 可以出现在operator= 左侧者

Rvalue: 只能出现在operator=右侧者

临时对象就是一种右值

1
2
3
4
5
int foo() { return 5; }
...
int x = foo(); // ok
int* p = &foo(); // error: 不可以对右值取引用,函数返回值属于右值
foo() = 7; // error
1
2
3
4
5
6
7
8
template <typename T>
class Myclass{
public:
Myclass();
Myclass(const T& t);
// 类需要有这样的构造函数且无异常才能支持move
Myclass(const T&& t) noexcept;
}

右值使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void process(int& i) { cout << "process(int&):" << i << endl; }
void process(int&& i) { cout << "process(int&&):" << i << endl; }
void forward(int&& i) {
cout << "forward(int&&):" << i << ",";
process(i);
}

int a=0;
process(a); // process(int&): 0
process(1); // process(int&&): 1
process(move(a)); // process(int&&): 0
// 不完美的传递(forwarding)
forward(2); // forward(int&&):2, process(int&):2
// 2经过传递之后变成了一个named object,即成了左值,因此调用process(int&)
forward(move(a)); // forward(int&&):0, process(int&):0
forward(a); // ERROR: 不能绑定int左值到int&&

const int& b = 1;
process(b); // ERROR:没有合适的函数调用‘process(const int&)’
process(move(b)); // 没有合适的函数调用'process(std::remove_reference<const int&>::type)'

int& x(5); // ERROR
process(move(x)); // ERROR: x未声明