如何确保使用移动构造函数

Oeb*_*ele 6 c++ move-constructor c++11 move-assignment-operator

下面的代码给出了错误:

use of deleted function ‘constexpr B::B(const B&)’
Run Code Online (Sandbox Code Playgroud)

现在,我知道这是因为通过指定移动构造函数(有意)隐式删除了复制构造函数,并且复制向量会导致对(已删除)复制构造函数的调用.我想我也理解为什么使用向量的复制构造函数和赋值运算符.我显然想要使用移动构造函数和赋值运算符:移动对象,因此也移动它包含的向量.那么,如何让我的移动构造函数/赋值运算符使用向量的移动构造函数/赋值运算符?

这是代码:

#include <vector>

class B {
private:
    /* something I don't want to copy */
public:
    B() {};
    B(B&& orig) {/* move contents */};
    B& operator=(B&& rhs) {
        /* move contents */
        return *this;
    };
};

class A {
private:
    vector<B> vec;
public:
    A() : vec() {};
    A(A&& orig) : vec(orig.vec) {};
    A& operator=(A&& rhs) {
        vec = rhs.vec;
        return *this;
    };
};
Run Code Online (Sandbox Code Playgroud)

Tar*_*ama 9

只需调用std::move要从中移动它们的表达式中的向量:

class A {
private:
    vector<B> vec;
public:
    A() : vec() {};
    A(A&& orig) : vec(std::move(orig.vec)) {};
    //                ^^^^^^^^^
    A& operator=(A&& rhs) {
        vec = std::move(rhs.vec);
        //    ^^^^^^^^^
        return *this;
    };
};
Run Code Online (Sandbox Code Playgroud)

即使你接受rvalue引用,rhs并且orig仍然是函数中的左值,所以你需要调用std::move它们.


Nia*_*all 5

要确保调用"move"构造函数和赋值运算符,您需要提供正确值类别的对象.值类别用于确定可以使用哪些运算符和构造函数.

用于std::move值类别(在本例中为左值)更改为xvalue(可以移动的左值).

// ...
A(A&& orig) : vec(std::move(orig.vec)) {};
A& operator=(A&& rhs) {
    vec = std::move(rhs.vec);
    return *this;
};
Run Code Online (Sandbox Code Playgroud)

move不复制或改变对象以任何方式,它仅仅是一个强制转换为参数类型的右值参考-因此修改值类别.