简体   繁体   English

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

[英]C++ auto with member initializer syntax and deleted copy constructor

class A
{
    int a;

public:

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

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

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

The above code does not compiles and i get the following error: C2280 'A::A(const A &)': attempting to reference a deleted function 上面的代码没有编译,我得到以下错误:C2280'A :: A(const A&)':尝试引用已删除的函数

I am using visual studio 2015 compiler. 我正在使用visual studio 2015编译器。 My understanding is with member initialization syntax compiler should directly use the default constructor which is what happens when there is no auto and in main i use A a{} . 我的理解是使用成员初始化语法编译器应该直接使用默认构造函数,这是在没有auto时发生的情况,而在main中我使用A a{} So i was wondering what is the deal with auto in this case. 所以我想知道在这种情况下与auto的交易是什么。

auto a = A {};

is only valid if A is copy constructible or move constructible. 仅当A是可复制的构造或移动构造时才有效。 The fact that you use auto is irrelevant. 您使用auto的事实无关紧要。 The same would be true for 同样的情况也是如此

A a = A {};

as well. 同样。

Declaring a copy constructor – even a delete d one – inhibits implicit declaration of a move constructor so your type A is neither copy constructible nor move constructible. 声明一个复制构造函数 - 甚至是delete一个 - 禁止隐式声明一个移动构造函数,因此你的类型A既不是可复制的,也不是可构造的。 If you add the line 如果添加该行

A(A&&) = default;

to the body of A , the code should compile again. 到了A的主体,代码应该再次编译。

In practice, the compiler will not actually call any copy or move constructor in this case and simply construct the object right in a . 实际上,在这种情况下,编译器实际上不会调用任何副本或移动构造函数,只需在a构造对象。 But the language rules demand that it must still reject the code which makes sense because whether a piece of code is allowed or not should not depend on an optional compiler optimization. 但是语言规则要求它仍然必须拒绝有意义的代码,因为一段代码是否被允许不应该依赖于可选的编译器优化。

This behavior will (most likely) change in C++17. 这种行为(很可能) 在C ++ 17中发生变化

Your understanding is correct, so let's see what's happening here, one step at a time. 你的理解是正确的,所以让我们一步一步看看这里发生了什么。

A {};

As you said, member initialization syntax, completely kosher here. 正如你所说,成员初始化语法,完全是犹太洁食。

auto a = (expression of some kind)

And then you're constructing auto a . 然后你正在构建auto a After performing type inference, this becomes equivalent to... 执行类型推断后,这相当于......

A a = (expression of some kind)

Which looks like a copy constructor. 这看起来像一个复制构造函数。 Which you deleted. 你删除了哪个。

you should use auto this way: 你应该这样使用auto:

auto a = new A();

if you don't want to use auto this is c++11 way: 如果您不想使用auto,这是c ++ 11方式:

A a{};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM