C ++ auto with member initializer syntax and deleted copy constructor

时间:2016-01-14 00:26:29

标签: c++

class A
{
    int a;

public:

    A(const A&) = delete;
    A& operator=(const A&) = delete;

    A() : a {0}
    { }
};

int main()
{
    auto a = A {};
}

上面的代码没有编译,我得到以下错误:C2280'A :: A(const A&)':尝试引用已删除的函数

我正在使用visual studio 2015编译器。我的理解是使用成员初始化语法编译器应该直接使用默认构造函数,这是在没有auto时发生的情况,而在main中我使用A a{}。所以我想知道在这种情况下与auto的交易是什么。

3 个答案:

答案 0 :(得分:8)

auto a = A {};

仅在A可复制或移动可构造时有效。您使用auto这一事实无关紧要。

也是如此
A a = A {};

声明一个复制构造函数 - 甚至是一个delete d - 禁止隐式声明移动构造函数,因此类型A既不是可复制构造也不是可构造的。如果添加行

A(A&&) = default;

A的主体,代码应该再次编译。

实际上,在这种情况下,编译器实际上不会调用任何副本或移动构造函数,只需在a中构造对象即可。但语言规则要求它仍然必须拒绝有意义的代码,因为一段代码是否允许不应该依赖于可选的编译器优化。

此行为(很可能)在C ++ 17中change

答案 1 :(得分:1)

您的理解是正确的,所以让我们一步一步看看这里发生了什么。

A {};

正如你所说,成员初始化语法,完全是犹太人。

auto a = (expression of some kind)

然后你正在构建auto a。执行类型推断后,这相当于......

A a = (expression of some kind)

它看起来像一个复制构造函数。你删除了哪个。

答案 2 :(得分:-4)

你应该以这种方式使用自动:

auto a = new A();

如果您不想使用auto,这是c ++ 11方式:

A a{};