删除的析构函数会改变 C++ 中的聚合初始化吗?

Fed*_*dor 6 c++ destructor aggregate default-constructor language-lawyer

代码如下

struct B {
    ~B() = delete;
};

B * b = new B{};
Run Code Online (Sandbox Code Playgroud)

在最新的 MSVC 中编译失败,出现错误:

error C2512: 'B': no appropriate default constructor available
note: Invalid aggregate initialization
Run Code Online (Sandbox Code Playgroud)

同时GCC和Clang都看不出代码有什么问题,demo: https: //gcc.godbolt.org/z/va9vcsEed

假设 MSVC 中只是一个错误是否正确?

总的来说,析构函数的存在或删除是否会改变聚合初始化的任何规则?

Vla*_*cow 7

C++ 标准中聚合概念的定义均未提及析构函数。

\n

例如,C++ 20 中聚合的定义(9.4.2 聚合)听起来如下

\n
\n

1 聚合是一个数组或一个类(第 11 条)

\n

(1.1) \xe2\x80\x94 没有用户声明或继承的构造函数 (11.4.5),

\n

(1.2) \xe2\x80\x94 没有私有或受保护的直接非静态数据成员 (11.9),

\n

(1.3) \xe2\x80\x94 无虚函数 (11.7.3),以及

\n

(1.4) \xe2\x80\x94 无虚拟、私有或受保护的基类 (11.7.2)。

\n
\n

如果在MS VS 2019中执行这条语句

\n
std::cout << std::is_aggregate_v<B> << '\\n';\n
Run Code Online (Sandbox Code Playgroud)\n

那么输出将为1.

\n

另一方面,如果满足以下条件,则默认构造函数被定义为已删除(C++ 20 标准,11.4.5.2 默认构造函数)

\n
\n

(2.8) \xe2\x80\x94 任何可能构造的子对象都具有带有析构函数的类型,该析构函数已从默认的默认构造函数中删除或无法访问。

\n
\n

但在提供的示例中没有这样的子对象。

\n

所以看来这是 MS VS 2019 的编译器错误。

\n