author:
- luixiao1223
title: 附录A
A.1 Rvalue references
int var=42;
int& ref=var; // 左值引用
ref=99;
assert(var==99);
左值和右值.
从简单来说左值就是在内存中有确定地址,长期贮存的元素.而右值普遍是临时对象.虽然在内存中存在,但是只是临时的.比如常亮
const char* p = "hello";
const int i=42;
其中hello,42就是典型的右值.(左值引用只能引用左值对象,右值引用只能引用右值对象.),如下面就会报错.
int& i = 42; // 编译报错.
可是你还是可以绑定到一个const型的左值引用(这是意外的情况,因为const的左值引用要特别重要)
int const& i = 42;
C++11引入了右值引用
int&& i=42;
int j=42;
int&& k=j;
move semantics
void process_copy(std::vector<int> && vec)
{
vec.push_back(42);
}
vector<int> test;
test.push_back(10);
//process_copy(test);// 报错
process_copy(std::move(test))//test被掏空之后,最好不要使用test了.
class X
{
private:
int* data;
public:
X():
data(new int[1000000])
{}
~X()
{
delete [] data;
}
X(const X& other):
data(new int[1000000])
{
std::copy(other.data,other.data+1000000,data);
}
X(X&& other):
data(other.data)
{
other.data=nullptr;
}
};
很多对象都是不能复制的,只能move
X x1;
X x2=std::move(x1);
X x3=static_cast<X&&>(x2); // 这种搞法也可以
再比如
std::thread, std::unique_lock<>, std::future<>, std::promise<>, and std::packaged_task<>
都是不能拷贝的,只能move
Rvalue references and function templates
template<typename T>
void foo(T&& t)
{}
foo(42);
foo(3.14159);
foo(std::string());
int i=42;
foo(i); // OK!. T被推断为int& 所以int& &&变成了int&. void foo<int&>(int& t);//为什么这样?这是C++的规则 (T&& && -> T&&) and (T& && -> T&).