Every object takes up at least 1 byte of space. The counter itself needs to take up at least 1 byte, but you also need space for the potential choices of object. Even if you use a union
, it still needs to be one byte. And it can't be the same byte as the counter.
Now, you might think that no_unique_address
could just come to the rescue, permitting the member union
to overlap with the counter if all of the union
elements are empty. But consider this code:
empty_type e{};
variant<empty_type> ve{in_place_index<0>}; //variant now stores the empty type.
auto *pve = ve.get_if<0>(); //Pointer to an `empty_type`.
memcpy(pve, &e, sizeof(empty_type)); //Copying from one trivial object to another.
The standard does not say that the members of a variant are "potentially-overlapping subojects" of variant
or any of its internal members. Therefore, it is 100% OK for a user to do a memcpy
from one trivial empty object to the other.
Which will overwrite the counter if it were overlapping with it. Therefore, it cannot be overlapping with it.
-O3
followed by-O2
– Nashvilleno_unique_address
current implementation is hit and miss. – Alphabetical