有没有办法让一个零大小的类型只能隐式构造?
用例是为了防止结构的某些公共成员通过大括号语法进行初始化:
class Barrier { ... };
struct Foo {
int user_sets;
int* this_to;
Barrier _bar;
int *must_be_zero_init_by_linker;
};
Foo foo = {1}; // ok
Foo bar = {1, nullptr}; // ok
Foo baz = {1, nullptr, {}}; // must error
编辑:另一个约束:Foo对象必须是链接器初始化的,因此它不能定义构造函数或私有成员。
答案 0 :(得分:5)
您可以定义自己的构造函数;这可以防止您的类成为聚合。例如:
struct Foo
{
Foo(int a = 0, int * p = nullptr) constexpr
: user_sets(a), this_to(p), must_be(nullptr)
{}
int user_sets;
int* this_to;
int *must_be;
};
Foo foo = { 1 }; // ok
Foo bar = { 1, nullptr }; // ok
// Foo baz = { 1, nullptr, {} }; // error
事实上,我建议制作构造函数explicit
- 然后你不能使用复制初始化,但你仍然可以使用列表初始化:
explicit Foo(int a = 0, int * p = nullptr) constexpr /* ... */
Foo foo { 1 }; // ok
Foo bar { 1, nullptr }; // ok
// Foo baz { 1, nullptr, {} }; // error
答案 1 :(得分:0)
是的,显式默认构造函数将起作用:
struct Barrier { explicit constexpr Barrier() {} };
这给出了你想要的行为:
Foo foo = {1}; // ok
Foo bar = {1, nullptr}; // ok
Foo baz = {1, nullptr, {}}; // error
请注意,行为可能会根据DR 1518的最终解决方案而改变,因此KerrekSB的答案更可靠,更不精确。