目标:能够对对象进行列表初始化,并使默认初始化将所有 POD 初始化为 0/ false
,并尽可能少地使用样板代码 (C++11)。
假设我有几个带有几个 POD 的类(想想文件格式解析)。为了不处理未定义的值,我希望将默认构造对象的值初始化为 0。例如,提供我自己的默认 c'tormemset()
在this
这种情况下可以正常工作,就像显式命名所有成员一样。
但是,这是样板文件。更重要的是,提供我自己的无参数默认构造函数会阻止我使用列表初始化语法进行成员初始化:
class Fails1 {
public:
int a, b;
Fails1() { memset(this, 0, sizeof(*this)); }
};
Fails1 this_works;
Fails1 this_fails{ 42, 54 }; // compiler error
我也可以为 the 添加构造函数initializer_list
,但这更像是样板文件。我想避免所有这些样板。
因此,我查看了当没有用户提供的默认构造函数时编译器提供的默认构造函数以及如何初始化它们的各种方法。这是我完全困惑的地方:
class A {
public:
int a, b;
};
有了这个类,我可以同时使用空初始化列表和带有值的初始化列表,而无需自己提供这两个构造函数;这是我想要的一部分。
// Example 1: default initialization
A a1;
第一个例子使用初始化;成员a
并且b
之后未定义(不是我想要的,我希望它们被值初始化)。
// Example 2: Value-initialization, so this works, I guess:
A a2 = A();
示例 2 使用值初始化,之后不复制。这就是我想要的,但是,我也认为空的大括号初始化列表会做同样的事情;请参见以下示例:
// Example 3: list-initialization with empty brace-init-list
A a3{};
示例 3 是我认为可以解决问题的方法。8.5.4“列表初始化”中描述了使用空大括号初始化列表的列表初始化:;特别是 8.5.4.3 说:“如果初始化列表没有元素并且 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
构造函数的能力?