gpt4 book ai didi

c++ - 空的括号初始化列表发出有关缺少字段初始化器的警告

转载 作者:可可西里 更新时间:2023-11-01 16:36:27 34 4
gpt4 key购买 nike

目标:能够列表初始化对象并拥有默认值使用尽可能少的样板将所有 POD 初始化为 0/false尽可能 (C++11)。

假设我有几个包含多个 POD 的类(想想文件格式解析)。为了不处理未定义的值,我想要默认构造的对象被值初始化为 0。例如,提供我自己的默认 c'tor memset()s this 工作正常这种情况,就像明确命名所有成员一样。

但是,这是样板文件。更重要的是提供我自己的无参数默认构造函数阻止我使用列表成员初始化的初始化语法:

class Fails1 {
public:
int a, b;
Fails1() { memset(this, 0, sizeof(*this)); }
};

Fails1 this_works;
Fails1 this_fails{ 42, 54 }; // compiler error

我也可以为 initializer_list 添加构造函数,但是那是更多的样板。我想避免所有这些样板。

所以我查看了编译器提供的默认构造函数没有用户提供的默认构造函数与如何初始化它们的各种方法。这是我得到的地方完全困惑:

class A {
public:
int a, b;
};

有了这个类,我既可以使用空的初始化列表,也可以使用那些具有值而不必自己提供两个构造函数;那是我想要的一部分。

// Example 1: default initialization
A a1;

第一个例子使用了初始化;成员 ab 是之后未定义(不是我想要的,我希望它们成为值初始化)。

// Example 2: Value-initialization, so this works, I guess:
A a2 = A();

示例 2 使用值初始化并且之后不复制。这就是我想要的,但是,我也认为空的 brace-init-lists 会做同样的事情;请参阅以下示例:

// Example 3: list-initialization with empty brace-init-list
A a3{};

示例 3 是我认为可以解决问题的方法。列表初始化在 8.5.4 中描述了一个空的 brace-init-list“列表初始化”:;特别是 8.5.4.3 说:“如果初始化程序list 没有元素并且 T 是具有默认构造函数的类类型,objectvalue-initialized”。但是,这会使用 g++ 4.7.2 发出警告使用 -Wextra:

missing initializer for member ‘A::a’ [-Wmissing-field-initializers]
missing initializer for member ‘A::b’ [-Wmissing-field-initializers]

虽然 clang++ 3.1 没有警告,所以它也可能是 g++ 中的错误。

回到我最初的问题。如何对对象进行值初始化无需提供我自己的样板默认构造函数——同时保留为其成员使用列表初始化的能力无需提供我自己的 initializer_list 构造函数?

最佳答案

这样的普通结构
struct A { int a,b; };

显然是一个聚合,而 A a {}; 显然是聚合初始化并暗示值初始化(即零初始化),如您已经引用的 §8.5.4/3 所述. (请特别注意下一段中给出的示例,它实际上与您的情况相同。)

GCC 警告非常具有误导性。

在搜索现有错误报告时,我找到了 this one ,这是您自己提交的。我认为这是正确的做法。

由于您已经制定了相关的标准部分,并且许多其他人在评论中做出了贡献,所以我将其作为社区 Wiki 答案。

关于c++ - 空的括号初始化列表发出有关缺少字段初始化器的警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14030467/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com