简体   繁体   中英

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

Is there any way to make a type that has zero size and can only be constructed implicitly?

The use case is to prevent some public members of a struct from being initialized via the brace syntax:

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

Edit: one other constraint: The Foo object must be linker initialized so it can't define constructors or private members.

You could define your own constructor; this prevents your class from being an aggregate. For example:

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

In fact, I would recommend making the constructor explicit - then you can't use copy-initialization, but you can still use list-initialization:

explicit Foo(int a = 0, int * p = nullptr) constexpr /* ... */

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

Yes, an explicit default constructor will work:

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

That gives the behaviour you want:

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

Note that the behaviour might change depending on the eventual resolution of DR 1518 , so KerrekSB's answer is more reliable and less subtle.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM