【问题标题】:How to value-initialize aggregate types with list-initialization如何使用列表初始化对聚合类型进行值初始化
【发布时间】:2015-04-24 20:58:16
【问题描述】:

如何在 C++14 中使用列表初始化语法对聚合类型进行值初始化?

Aggregate_t {}; 

这被视为聚合初始化,它会为 Aggregate_t 的未初始化成员产生错误或警告。

这可能吗?

编辑:示例

struct Aggregate_t {
  int x;
};

int main (int, char**)
{
  Aggregate_t {};
  return 0;
}

用g++-4.9.2编译:

main.c++: In function ‘int main(int, char**)’:
main.c++:7:16: warning: missing initializer for member ‘Aggregate_t::x’ [-Wmissing-field-initializers]
   Aggregate_t {};
            ^

【问题讨论】:

  • 请发布MCVE,以及您遇到的错误。
  • 这应该与值初始化具有相同的效果(除非自 C++11 以来发生了一些变化——我还没有完全更新)。你真的得到错误,或者只是过分热心的警告?另外,请告诉我们Aggregate_t 的定义,以便我们检查它是否真的是一个聚合。
  • 这可能是一个过分热心的警告,但问题更多的是关于初始化的影响。如果聚合初始化的未初始化成员是值初始化的(根据标准),那么我想这就是我的问题的答案。
  • @KarolyHorvath 除了{} 确实初始化了该成员。
  • 我认为这是一个过分热心的警告,通常默认禁用它。

标签: c++ c++14 value-initialization list-initialization aggregate-initialization


【解决方案1】:

[dcl.init.aggr]

7 - 如果列表中的 initializer-clauses 少于聚合中的成员,则每个未显式初始化的成员都应初始化 [C++14: 从它的 brace-or-equal-initializer 或者,如果没有 brace-or-equal-initializer,] 从一个空的初始化列表 (8.5.4) .

所以 g++ 对它的警告过于热心了;我不知道有一种方法可以避免它,同时在警告有效的情况下保留它,当然除了使用带有预期复制省略的复制初始化:

Aggregate_t a = Aggregate_t();

【讨论】:

  • 我在cppreference.com也找到了:“如果初始化子句的数量小于成员的数量或者初始化子句完全为空,则剩余的成员通过它们的大括号或等号进行初始化初始化器,如果在类定义中提供,否则由空列表提供,它执行值初始化。”因此,它通常应该具有与值初始化相同的效果。
  • 重点是不必使用 -() 语法来避免 gcc 的警告。好像做不到,所以,谢谢!
  • 正如警告的名称所暗示的,-Wmissing-field-initializers 是为了缺少初始化程序——即使在初始化底层事物时(根据manual)。然而,它被设计为有例外,空括号就是其中之一。根据我的经验,GCC 在这方面不是很擅长,所以如果你确信它不会隐藏错误,我会推荐 -Wno-missing-field-initializers
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-24
  • 2017-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-21
相关资源
最近更新 更多