首页 > 解决方案 > 可以默认初始化具有已删除默认构造函数的类类型吗?

问题描述

根据 cppref 关于值初始化的说法

如果 T 是一个没有默认构造函数或用户提供或删除的默认构造函数的类类型,则该对象是默认初始化的

但是既然那个类类型已经删除了默认构造函数,那么这个对象怎么会被默认初始化呢?

据我所知,类类型的默认初始化需要默认构造函数的访问。如果我们有:

struct A {
    A() = delete;
    int k;
};

然后A *a = new A;会失败,A* a = new A();.

但是A a{};没关系。但为什么?根据cppreference

否则,如果括号初始化列表为空且 T 是具有默认构造函数的类类型,则执行值初始化。

标签: c++c++11initializationlanguage-lawyer

解决方案


我认为该标准只是意味着“如果T是具有已删除默认构造函数的类类型,则转到默认初始化”。它最终会失败,因为为默认初始化选择的构造函数被删除了。它用于区分第二种情况,即“如果T是具有既不是用户提供也不是删除的默认构造函数的类类型”,对于这种情况,首先执行零初始化,然后默认初始化如果T有一个非平凡默认构造函数。

A a{}可以,但是为什么呢?

因为什么时候A聚合类型,聚合初始化被执行了。请注意,自 C++11 起,聚合类型允许显式删除的构造函数。

在所有情况下,如果使用空的大括号 {} 对并且 T 是聚合类型,则执行聚合初始化而不是值初始化。

聚合是以下类型之一:

  • 数组类型
  • 类类型(通常是结构或联合),具有
    • 没有私有或受保护的非静态数据成员
    • 没有用户提供的, inherited, or explicit (since C++17)构造函数(explicitly defaulted or deleted constructors are allowed) (since C++11)

推荐阅读