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.