【问题标题】:Why does 'A a{};' compile when the default constructor A::A() is deleted? [duplicate]为什么'A a{};'删除默认构造函数 A::A() 时编译? [复制]
【发布时间】:2019-01-04 11:57:22
【问题描述】:

这是有问题的代码示例:

struct A {
    A() = delete;
};

int main()
{
//  A a(); // compiles, since it's a function declaration (most vexing parse)
//  A a;   // does not compile, just as expected
    A a{}; // compiles, why? The default constructor is deleted.
}

使用任何可用的编译器尝试here。我尝试了几个,但没有找到一个编译错误。

【问题讨论】:

标签: c++ c++11 language-lawyer uniform-initialization


【解决方案1】:

这是一个当前的语言问题,很可能很快就会得到解决。可以找到解决必要设计更改的提案here。来自提案的摘要:

C++ 目前允许通过聚合初始化某些具有用户声明的构造函数的类型 初始化,绕过那些构造函数。结果是令人惊讶的、令人困惑的代码, 和越野车

【讨论】:

  • “语言缺陷”是指特定的东西。这不是语言缺陷。这是设计上的改变。
  • @Barry 感谢您的提示,我会修复它。
【解决方案2】:

因为Aaggregate type,所以给定A a{};会执行聚合初始化。

每个direct public base, (since C++17) 数组元素或非静态类成员,按照类定义中数组下标/外观的顺序,从初始化器列表的相应子句复制初始化。

在聚合初始化中,每个成员或元素(如果有的话)将被直接复制初始化,构造函数被绕过;所以deleteed 与否无关紧要。

请注意,聚合类型允许显式删除的构造函数(C++11 起)(C++20 前),

没有用户提供的构造函数(允许显式默认或删除的构造函数)(C++11 起)(C++17 前)

没有用户提供的、继承的或显式的构造函数(允许显式默认或删除的构造函数)(C++17 起)(C++20 前)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-04
    • 1970-01-01
    • 2011-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-27
    相关资源
    最近更新 更多