只能隐式构造的c++ 11类

C++11 class that can only be implicitly constructed?

本文关键字:c++ 11类      更新时间:2023-10-16

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

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

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

你可以定义自己的构造函数;这可以防止您的类成为聚合。例如:

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

是的,一个显式的默认构造函数可以工作:

struct Barrier { explicit constexpr Barrier() {} };

给出你想要的行为:

Foo foo = {1};               // ok
Foo bar = {1, nullptr};      // ok
Foo baz = {1, nullptr, {}};  // error

请注意,行为可能会根据DR 1518的最终分辨率而改变,因此KerrekSB的答案更可靠,更不微妙。