c++ - 可以默认初始化具有已删除默认构造函数的类类型吗?

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

根据 cppref 关于 value initialization 的说法

if T is a class type with no default constructor or with a user-provided or deleted default constructor, the object is default-initialized;

但由于该类类型删除了默认构造函数,对象如何被默认初始化?

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

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

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

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

Otherwise, If the braced-init-list is empty and T is a class type with a default constructor, value-initialization is performed.

最佳答案

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

A a{} is OK,but why?

因为 Aaggregate type执行聚合初始化。请注意,自 C++11 起,聚合类型允许显式删除构造函数。

In all cases, if the empty pair of braces {} is used and T is an aggregate type, aggregate-initialization is performed instead of value-initialization.

An aggregate is one of the following types:

  • ...
  • class type (typically, struct or union), that has
    • ...
    • no user-provided, inherited, or explicit constructors (explicitly defaulted or deleted constructors are allowed) (since C++17) (until C++20)
    • ...

编辑

从 C++20 开始,行为发生了变化; A a{}; 会失败。

An aggregate is one of the following types:

  • ...
  • class type (typically, struct or union), that has
    • ...
    • no user-declared or inherited constructors (since C++20)
    • ...

A 不再是聚合。 A a{}; 执行 value-initialization ( default-initialization ),删除的构造函数被使用并失败。

关于c++ - 可以默认初始化具有已删除默认构造函数的类类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50393837/

相关文章:

c++ - pcl::PCLPointCloud2 用法

c++ - 将空字符串传递给构造函数

ios - 在 Swift 中声明实例变量 : optional vs forced unwrapping vs initial value

C# 泛型与 C++ 模板的比较

c++ - 通过引用将参数传递给 std::thread 函数是否安全?

c++ - 如何在 header 中声明由函数初始化的全局常量?

c++ - 从 Boost 迁移到 C++11 的标准库

c - 如何在 C 中使用带有嵌套结构的指定 init ?

java - Eclipse 不认为 System.exit 会中断执行

c++ - OpenMP 中的信号