为什么在删除默认构造函数 A::A() 时 'A a{};' 可以编译?
Why does 'A a{};' compile when the default constructor A::A() is deleted?
这里是有问题的代码示例:
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。我尝试了几个,但没有找到一个给出编译错误的。
这是一个当前的语言问题,很可能很快就会得到解决。可以找到解决必要设计变更的提案 here。来自提案摘要:
C++ currently allows some types with user-declared constructors to be initialized via aggregate
initialization, bypassing those constructors. The result is code that is surprising, confusing,
and buggy
因为A
是一个aggregate type,那么给定的A a{};
进行聚合初始化。
Each direct public base, (since C++17)
array element, or non-static class member, in order of array subscript/appearance in the class definition, is copy-initialized from the corresponding clause of the initializer list.
在聚合初始化中,每个成员或元素(如果有的话)将被直接复制初始化,构造函数被绕过;所以 delete
ed 与否并不重要。
注意聚合类型允许显式删除构造函数 (C++11 起) (C++20 前),
no user-provided constructors (explicitly defaulted or deleted constructors are allowed) (since C++11) (until C++17)
no user-provided, inherited, or explicit constructors (explicitly defaulted or deleted constructors are allowed) (since C++17) (until C++20)
这里是有问题的代码示例:
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。我尝试了几个,但没有找到一个给出编译错误的。
这是一个当前的语言问题,很可能很快就会得到解决。可以找到解决必要设计变更的提案 here。来自提案摘要:
C++ currently allows some types with user-declared constructors to be initialized via aggregate initialization, bypassing those constructors. The result is code that is surprising, confusing, and buggy
因为A
是一个aggregate type,那么给定的A a{};
进行聚合初始化。
Each
direct public base, (since C++17)
array element, or non-static class member, in order of array subscript/appearance in the class definition, is copy-initialized from the corresponding clause of the initializer list.
在聚合初始化中,每个成员或元素(如果有的话)将被直接复制初始化,构造函数被绕过;所以 delete
ed 与否并不重要。
注意聚合类型允许显式删除构造函数 (C++11 起) (C++20 前),
no user-provided constructors (explicitly defaulted or deleted constructors are allowed) (since C++11) (until C++17)
no user-provided, inherited, or explicit constructors (explicitly defaulted or deleted constructors are allowed) (since C++17) (until C++20)