为什么defaulted-move-ctor禁止隐式copy-ctor而不抑制defaulted-copy-ctor?

时间:2018-11-22 02:10:38

标签: c++ standards copy-constructor default-copy-constructor

我似乎遇到了一个示例,其中默认的move构造函数似乎视情况而定是用户声明的和非用户声明的:

struct Foo {
    int a;
    Foo():a(42){};
    //Foo(const Foo & other) = default;
    Foo(Foo && other) = default;

};

int main() {
    Foo f;
    Foo g = f;
}

结果:

test.cpp:11:9: error: call to implicitly-deleted copy constructor of 'Foo'
    Foo g = f;
        ^   ~
test.cpp:5:5: note: copy constructor is implicitly deleted because 'Foo' has a user-declared move constructor
    Foo(Foo && other) = default;
    ^

由于cppreference告诉我们,这是预期的编译器错误:

  

类T的隐式声明或默认副本构造函数为   如果满足以下任一条件,则定义为已删除:
  [...]
  T具有用户定义的move构造函数或move赋值运算符;

请注意,默认构造函数在这里显然算作“用户声明的”。 但是,如果我们现在从第4行删除注释,从而显式默认使用副本构造函数,则即使我上面引用的语句指定了以下内容,该程序也将正确编译:

  

隐式声明的或默认的复制构造函数

这似乎是一个矛盾。这是cppreference中的错误还是我只是感到困惑?

2 个答案:

答案 0 :(得分:2)

这看起来像cppreference的错误。声明移动构造函数/赋值运算符只会删除隐式声明的副本构造函数。实际上,将副本构造函数声明为默认值就是用户声明它,因此不适用于这种情况。

答案 1 :(得分:0)

  

为什么default-move-ctor禁止隐式copy-ctor而不抑制defaulted-copy-ctor?

因为当您将构造函数定义为默认值时,您将重新建立由move构造函数引起的删除效果,因此,默认情况下,复制构造函数的作用与显式定义它的作用相同。