使用unique_ptr交换类

问题描述 投票:0回答:1
#include <memory>
#include <algorithm>

using namespace std;

class A {
public:
    unique_ptr<int> u;
    A(){}
    A(const A& other): u(new int(*other.u)){} // If I comment this out, it works.
    // A(A&&){} // This does not help.
};

int main() {
    A a;
    A b = a;
    swap(a, b);
}

此代码不起作用 - 失败时出现模板错误,表示no matching function for call to ‘swap(A&, A&)’。为什么?删除第二个构造函数会有所帮助,但我需要在其他代码中使用它。我猜测它可以与其他定义的一些构造函数的自动删除相关联,但手动添加移动构造函数也无济于事。我怎样才能解决这个问题?

c++ swap unique-ptr
1个回答
5
投票

std::swap()要求其参数是可移动构造和移动可分配的。

鉴于:

struct A {
    unique_ptr<int> u;
    A();
};

由于隐式定义的移动构造函数和移动赋值运算符,A是可交换的。

但是,鉴于:

struct A {
    unique_ptr<int> u;
    A();
    A(A const&);
};

通过声明用户定义的复制构造函数,您将禁止A的移动构造函数和移动赋值运算符的隐式定义(并且通过具有不可赋值可复制的成员,您将禁止隐式生成A的复制构造函数和复制赋值运算符)。

要使A再次交换,您需要用户定义两个(*):

struct A {
    unique_ptr<int> u;
    A();
    A(A const&);
    A(A&&);
    A& operator=(A&&);
};

或两者都没有,只需添加适当的副本分配:

struct A {
    unique_ptr<int> u;
    A();
    A(A const&);
    A& operator=(A const&);
};

但是,这可能会破坏你最初避免交换深度拷贝的意图,所以你最终可能会最终定义所有这些。


(*)noexcept规范仅为简洁而省略...

© www.soinside.com 2019 - 2024. All rights reserved.