首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >浮动成员是否保证使用{}语法初始化为零?

浮动成员是否保证使用{}语法初始化为零?
EN

Stack Overflow用户
提问于 2021-10-18 08:35:48
回答 2查看 397关注 0票数 6

在C++17中,假设S是一个带有已删除的默认构造函数的结构和一个浮点成员,当S用空大括号初始化时,标准保证浮动成员为零初始化吗?

代码语言:javascript
复制
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不一定是零。

还有一种讨论似乎意味着,尽管没有保证,所有已知的编译器都是零初始化的:

该标准指定在类具有用户提供或删除的默认构造函数时不执行零初始化,即使该默认构造函数不是通过重载解析选择的。如果选择了未删除的默认默认构造函数,所有已知编译器都会执行额外的零初始化.

如果构造函数被显式地默认或删除,为什么聚合初始化在C++20之后不再工作?相关

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-10-18 13:29:07

因为S是一个聚合,所以S{}将执行聚合初始化。标准中关于在列表中没有初始化项时如何初始化成员的规则是基本上你所引用的

  • 如果元素具有默认的成员初始化器(class.mem),则从该初始化器初始化元素。
  • 否则,如果元素不是引用,则元素将从空初始化程序列表(dcl.init.list)复制初始化。

所以对于b,这相当于float b = {};。根据列表初始化的规则,我们必须得到一路降至3.10

否则,如果初始化程序列表没有元素,则对象是值初始化的.

值初始化将将float初始化为0。

票数 4
EN

Stack Overflow用户

发布于 2021-10-18 08:55:25

这是C++的一个怪癖,也就是固定在C++20中。同时,可以将explicit添加到已删除的默认构造函数中,以强制结构成为非聚合结构,并使代码成为一个有保证的编译错误:

代码语言:javascript
复制
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'
}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69613009

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档