【问题标题】:Move assignable class containing vector<unique_ptr<T>>移动包含 vector<unique_ptr<T>> 的可分配类
【发布时间】:2015-07-15 12:34:03
【问题描述】:

类 Foo 有一个右值引用构造函数,它移动 unique_ptrs 的包含向量,那么为什么下面的代码会给出以下错误,无论 main 中的 Foo() 上是否有 std::move

error C2280: 'std::unique_ptr<SomeThing,std::default_delete<_Ty>> &std::unique_ptr<_Ty,std::default_delete<_Ty>>::operator =(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : attempting to reference a deleted function
class Foo{
public:
    Foo(){

    }
    Foo(Foo&& other) :
        m_bar(std::move(other.m_bar))
    {};

    std::vector<std::unique_ptr<SomeThing>> m_bar;
};

int main(int argc, char* argv[])
{
    Foo f;
    f = std::move(Foo());
    return 0;
}

【问题讨论】:

    标签: c++ move-semantics rvalue-reference


    【解决方案1】:

    这个:

     f = std::move(Foo());
    

    不调用移动构造函数。它调用移动赋值运算符。此外,它是多余的,因为 Foo() 已经是一个右值,所以它相当于:

    f = Foo();
    

    由于您声明了移动构造函数,因此没有声明移动赋值运算符 - 所以没有。所以你要么必须提供一个:

    Foo& operator=(Foo&& other) {
        m_bar = std::move(other.m_bar);
        return *this;
    }
    

    或者,由于您的所有成员都自己实现移动操作,您可以删除移动构造函数并依赖编译器生成的隐式移动构造函数和移动赋值。

    【讨论】:

    • 删除移动构造函数和/或 Foo() 上的 std::move() 似乎不会停止编译错误。
    • 移动赋值运算符的定义加上 return *this。行得通。
    • @EdwardJBrown: Works on gcc
    • @AndyG 在 vs2013 msvc 中似乎不起作用,只是使用了您的确切代码并得到了同样的错误。可能是微软的错误。还是谢谢
    • @EdwardJBrown:根据您的实际代码(而不是这个玩具问题),您可能会通过定义复制构造函数/赋值来隐式删除移动构造函数/赋值
    猜你喜欢
    • 2018-02-02
    • 2019-11-07
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    • 2015-04-30
    • 2015-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多