在C++17中,假设S是一个带有已删除的默认构造函数的结构和一个浮点成员,当S用空大括号初始化时,标准保证浮动成员为零初始化吗?
struct A {
int x{};
};
struct S
{
S() = delete;
A a;
float b;
};
int main()
{
auto s = S{}; // Is s.b guaranteed to be zero?
}在我看来,cppreference.com并不清楚,他们都说:
如果初始化器子句的数量小于成员数,而basesor初始化程序列表完全为空,则其余成员和基(自C++17)将由其默认成员初始化器(如果在类定义中提供)初始化,并根据通常的列表初始化规则(对具有默认构造函数的非类类型和非聚合类进行值初始化,以及聚合初始化)从空列表中复制初始化。如果引用类型的成员是这些剩余成员之一,则程序是不正确的。
(从这里开始),这意味着b保证为零。
在所有情况下,如果使用空大括号{}且T是聚合类型,则执行聚合初始化而不是值初始化。
(从这里开始)
这意味着b不一定是零。
还有一种讨论似乎意味着,尽管没有保证,所有已知的编译器都是零初始化的:
该标准指定在类具有用户提供或删除的默认构造函数时不执行零初始化,即使该默认构造函数不是通过重载解析选择的。如果选择了未删除的默认默认构造函数,所有已知编译器都会执行额外的零初始化.
发布于 2021-10-18 13:29:07
发布于 2021-10-18 08:55:25
这是C++的一个怪癖,也就是固定在C++20中。同时,可以将explicit添加到已删除的默认构造函数中,以强制结构成为非聚合结构,并使代码成为一个有保证的编译错误:
struct A {
int x{};
};
struct S
{
explicit S() = delete;
const A a;
const float b;
};
int main()
{
auto s = S{}; // error: call to deleted constructor of 'S'
}https://stackoverflow.com/questions/69613009
复制相似问题