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类型,所以不会调用。

 

posted @ 2022-11-17 21:54  lypbendlf  阅读(74)  评论(0编辑  收藏  举报