为什么“ A a {};”删除默认构造函数A :: A()时进行编译?

时间:2018-07-27 11:00:53

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

这是有问题的代码示例:

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进行尝试。我尝试了几种,但没有发现编译错误。

2 个答案:

答案 0 :(得分:5)

这是当前的语言问题,很可能很快会得到解决。解决here的提案可以解决必要的设计更改。从提案摘要开始:

  

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

答案 1 :(得分:2)

由于Aaggregate type,因此在给定A a{};的情况下执行聚合初始化。

  

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

在聚合初始化中,每个成员或元素(如果有)将直接进行复制初始化,而忽略构造函数;因此无论是否delete都无关紧要。

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

  

没有用户提供的构造函数(允许使用默认的默认构造函数或删除的构造函数)(自C ++ 11起)(直到C ++ 17)

     

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