C++ 自动使用成员初始值设定项语法和已删除的复制构造函数

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

本文关键字:语法 删除 构造函数 复制 成员 C++      更新时间:2023-10-16
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编译器。我的理解是成员初始化语法编译器应该直接使用默认构造函数,这是在没有自动时发生的情况,并且主要使用A a{}。所以我想知道在这种情况下与汽车有什么关系。

auto a = A {};

仅当A可复制可构造或移动可构造时才有效。您使用auto的事实无关紧要。对于

A a = A {};

也。

声明复制构造函数(即使是delete d 构造函数)会禁止移动构造函数的隐式声明,因此您的类型A既不是复制可构造的,也不是移动可构造的。如果添加该行

A(A&&) = default;

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

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

此行为(很可能)将在 C++17 中更改。

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

A {};

正如你所说,成员初始化语法在这里完全犹太洁食。

auto a = (expression of some kind)

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

A a = (expression of some kind)

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

你应该这样使用auto:

auto a = new A();

如果你不想使用auto,这是C ++ 11的方式:

A a{};