私有构造函数和聚合初始化:意外的交互
在 C 中,将默认构造函数声明为私有会自然地导致人们假设关联类型的默认构造将变得不可访问。然而,当使用大括号括起来的初始化语法时,会出现一种奇怪的行为。
考虑以下示例:
class C { C() = default; }; int main() { C c; // error: C::C() is private auto c2 = C(); // error: calling a private constructor }
意外的是,上述代码在所有主要编译器上都会生成错误。这是预期的行为,因为默认构造函数确实被声明为私有的。然而,使用大括号括起来的初始化突然允许默认构造:
int main() { C c{}; // OK auto c2 = C{}; // OK }
这种意外行为背后的原因在于 C 标准库的复杂性。根据 C 14 标准 (8.4.2/5),如果函数是用户声明的并且在第一次声明时未显式默认或删除,则该函数被视为“用户提供的”。
在以下情况下在上面的 C 类中,默认构造函数在其第一个声明中显式默认。这意味着它不被视为“用户提供的”。因此,C 类没有用户提供的构造函数,这使其根据 8.5.1/1 中的定义成为聚合:
An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).
因此,C 允许使用大括号括起来的初始化类,允许默认构造,即使构造函数被声明为私有。这种行为可能会令人惊讶,并且在某些情况下可能会导致不良后果。
以上是为什么我可以使用私有默认构造函数初始化聚合?的详细内容。更多信息请关注PHP中文网其他相关文章!