当前位置: 首页 > 知识库问答 >
问题:

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

东方飞捷
2023-03-14

在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?
}

在我看来,CPPFerence。com并不清楚,他说:

如果初始值设定项子句的数量小于成员的数量,并且基或初始值设定项列表完全为空,则剩余的成员和基(自C 17起)由其默认成员初始值设定项初始化(如果在类定义中提供),否则(自C 14起)从空列表复制初始化,根据常见的列表初始化规则(使用默认构造函数对非类类型和非聚合类执行值初始化,并对聚合执行聚合初始化)。如果引用类型的成员是这些剩余成员之一,则程序的格式不正确。

(从这里开始),这意味着b保证为零

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

(从这里)

这意味着b不能保证为零。

还有一个讨论似乎暗示,虽然不能保证,但所有已知的编译器无论如何都是零初始化的:

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

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

共有2个答案

尹俊雅
2023-03-14

由于S是一个聚合,因此S{}将执行聚合初始化。标准中关于在列表中没有初始值设定项时如何初始化成员的规则基本上是您引用的:

  • 如果元素具有默认的成员初始值设定项([class.mem]),则该元素将从该初始值设定项初始化

对于b,这相当于〈代码〉浮点b={} 。根据列表初始化规则,我们必须一直向下到3.10:

否则,如果初始值设定项列表没有元素,则对象为值初始化。

值初始化将浮动初始化为0。

伏建修
2023-03-14

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

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'
}
 类似资料:
  • 问题内容: 我最近刚与Python中的一个错误作斗争。那是那些愚蠢的新手错误之一,但是它让我思考了Python的机制(我是C ++的老程序员,是Python的新手)。我将列出错误的代码并解释如何解决该问题,然后我有两个问题。 场景:我有一个叫做A的类,它有一个字典数据成员,下面是其代码(当然这是简化的): 使用此代码的类为B类: 请注意,每次调用都会初始化类A的新“干净”实例,并在添加前后打印字典

  • 此代码编译: 该代码不: 报告的错误(在 MSVC、gcc 和 clang 中)表明他们认为 构造函数未定义或不是 ,例如。从叮叮当当: 为什么? (可能与这个问题有关,但在使用时应该是完整的;只有仍然不完整。

  • 本文向大家介绍Visual Basic .NET成员初始化,包括了Visual Basic .NET成员初始化的使用技巧和注意事项,需要的朋友参考一下 示例 每个枚举成员可以用一个值初始化。如果未为成员指定值,则默认情况下将其初始化为0(如果它是成员列表中的第一个成员),或者初始化为比前一个成员的值大1的值。            

  • 问题内容: 也许这比技术问题更像是一种样式问题,但是我有一个包含多个成员变量的类,并且我想让它起作用,以便在用户第一次创建该类的实例时初始化一些成员变量(即在该功能),我想其他的成员变量从成员函数参数,将稍后被称为定义。所以我的问题是我应该初始化函数中的所有成员变量(并将稍后定义的变量设置为虚拟值)还是初始化函数中的某些成员以及后续函数中的某些成员变量。我意识到这可能很难理解,因此这里有一些示例。

  • 在C++98标准里,只有static const声明的整型成员能在类内部初始化,并且初始化值必须是常量表达式。这些限制确保了初始化操作可以在编译时期进行。例如: int var = 7; class X { static const int m1 = 7; // 正确 const int m2 = 7; // 错误:无static static int m3 =

  • 如果我有一个struct Foo和一个struct Bar: 如果我初始化一个条并打印正确得到的值: 但是现在如果我声明这样的构造函数: 我失去了Bar::foo的默认构造,程序输出了32764 0 5! 为什么我不得不像这样无声地初始化每个成员变量: 只要我声明一个构造函数?在这种情况下,为什么默认构造不起作用?