std::move() 学习
转自:https://stackoverflow.com/questions/28595117/why-can-we-use-stdmove-on-a-const-object
1.右值
int
a = 10;
左值是有固定的内存地址,&a即左值的地址,我们可以把&a保存起来,后续通过&a这个地址读取、修改a的内容;而右值是一种临时的值,我们很难获取到右值的地址,如上面的10,10的地址在哪里呢,通过常规的代码是很难获取到10的内存地址的,或者即使获取到右值的地址,该地址可能很快失效了,不能后续使用了。
2.std::move
https://blog.csdn.net/zzhongcy/article/details/86747794
emplace_back必须要结合std::move强制将左值转换为右值,
-
当自定义类A没有移动构造函数时,vec.emplace_back(std::move(a))也等效与vec.push_back(a)。
https://stackoverflow.com/questions/35404932/stdvectoremplace-back-and-stdmove,临时变量不需要std::move,emplace会直接进行完美转发构造对象,然后加入。
例子:
#include <vector> #include <string> #include <iostream> using namespace std; int main() { vector<string> vec{"1","2","3"}; vector<string> v2; for(const auto& v:vec){ v2.emplace_back(std::move(v)); } for(const auto&v:vec){ cout<<v<<endl; } for(const auto&v:v2){ cout<<v<<endl; } return 0; }
输出:
1 2 3 1 2 3
居然两个都有值,而且遍历的时候我还是const &方式,这种情况下仍然能够调用string的转移构造函数?
上述是因为const类型不会调用移动构造函数的!!!就还是拷贝构造函数。
#include <vector> #include <string> #include <iostream> using namespace std; struct CAT { CAT(){} CAT(const CAT&) {std::cout << "COPY"<<endl;} CAT(CAT&&) {std::cout << "MOVE"<<endl;} }; int main() { const string a("123"); //a非const时,std::move后打印a为空 vector<string> vec; vec.emplace_back(std::move(a)); cout<<vec[0]<<"\n"; cout<<a<<endl; const CAT cat; CAT cat2 = std::move(cat); return 0; }
输出:
123 123 COPY
CAT结构体是有移动构造函数的,但是由于是const类型,所以不会调用。