akr*_*ki1 0 c++ swap unique-ptr
#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);
}
Run Code Online (Sandbox Code Playgroud)
此代码不起作用 - 失败,出现模板错误no matching function for call to ‘swap(A&, A&)’.为什么?删除第二个构造函数会有所帮助,但我需要在其他代码中使用它.我猜测它可以与其他定义的一些构造函数的自动删除相关联,但手动添加移动构造函数也无济于事.我怎样才能解决这个问题?
std::swap()要求它的参数是可移动构造和移动可分配的.
鉴于:
struct A {
unique_ptr<int> u;
A();
};
Run Code Online (Sandbox Code Playgroud)
A 由于隐式定义的move-constructor和move-assignment运算符,它是可交换的.
但是,鉴于:
struct A {
unique_ptr<int> u;
A();
A(A const&);
};
Run Code Online (Sandbox Code Playgroud)
通过声明用户定义的复制构造函数,您将禁止A移动构造函数和移动赋值运算符的隐式定义(并且通过具有不可赋值可复制的成员,您将禁止隐式生成A的复制构造函数和副本赋值运算符).
要A再次进行交换,您需要用户定义两个(*):
struct A {
unique_ptr<int> u;
A();
A(A const&);
A(A&&);
A& operator=(A&&);
};
Run Code Online (Sandbox Code Playgroud)
或两者都没有,只需添加适当的副本分配:
struct A {
unique_ptr<int> u;
A();
A(A const&);
A& operator=(A const&);
};
Run Code Online (Sandbox Code Playgroud)
但是,这可能会破坏你最初避免交换深度拷贝的意图,所以你最终可能会最终定义所有这些.
(*)noexcept规范仅为简洁而省略...