C ++ 11类只能隐式构造?

时间:2014-03-10 21:05:07

标签: c++ c++11

有没有办法让一个零大小的类型只能隐式构造?

用例是为了防止结构的某些公共成员通过大括号语法进行初始化:

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对象必须是链接器初始化的,因此它不能定义构造函数或私有成员。

2 个答案:

答案 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的答案更可靠,更不精确。