C++ 11中出现了move函数,自己平时几乎没使用过,不过看很多源码都有move的使用,而且在看《代码整洁之道》《c++性能优化指南》等书籍的时候都对该函数有推荐,不过这其中涉及到了其他的知识,比如左值,右值得概念,所以一直也没空对其进行梳理总结,下面是一点自己看书的理解:
- std::move()是什么?
std::move()学术上是一个函数,其实实际不是一函数,它只是传话筒,告诉编译器一个左值可以被“劫掠”啦。 - std::move()能做什么?
它只是传话筒,告诉编译器一个左值可以被“劫掠”啦,换句话说就是告诉编译器“现在你可以毁灭我了,拿走我的所有内存呀什么的”string str = "hello"; std::move(x);//不会有任何效果,因为编译器并没有摧毁,因为没有找到一个接盘侠 cout << str << endl;//show "hello" string robber = std::move(x);//找到了一个强盗接盘 cout << str << endl;//show " " cout << robber<< endl;//show "hello"
- std::move()什么时候使用?
例子:
此外常用在STL中,常见的是push_back(std::move(str))template <class T> swap(T& a, T& b) { T tmp(a); // we now have two copies of a a = b; // we now have two copies of b (+ discarded a copy of a) b = tmp; // we now have two copies of tmp (+ discarded a copy of b) } template <class T> swap(T& a, T& b) { T tmp(std::move(a)); a = std::move(b); b = std::move(tmp); }
下面是一专业术语的解释:
左值:可以取地址,有名字的就是左值
右值:反之
举个例子,int a = b+c, a 就是左值,其有变量名为a,通过&a可以获取该变量的地址;表达式b+c、函数int func()的返回值是右值,在其被赋值给某一变量前,我们不能通过变量名找到它,&(b+c)这样的操作则不会通过编译。
将亡值:将亡值可以理解为通过“盗取”其他变量内存空间的方式获取到的值。比如返回右值引用T&&的函数返回值、std::move的返回值,或者转换为T&&的类型转换函数的返回值。
注意:
- 右值引用变量, 在表达式中使用时会变成左值(参考上面代码的最后几行);
- 一个函数接受右值引用作为参数, 在函数中会变成左值引用(所以才要实现完美转发).
void f(int& x) { cout << "1" << endl; }
void f(const int& x) { cout << "2" << endl; }
void f(int&& x) { cout << "3" << endl; }
int main() {
int i = 1;
const int ci = 2;
f(i); // calls f(int&)
f(ci); // calls f(const int&)
f(3); // calls f(int&&)
// would call f(const int&) if f(int&&) overload wasn't provided
f(std::move(i)); // calls f(int&&)
// rvalue reference variables are lvalues when used in expressions
int&& x = 1;
f(x); // calls f(int& x)
f(std::move(x)); // calls f(int&& x)
}