Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is std::variant unable to hold array object types while union can?

Here is simple example, We can define a low level union like this :

static union
{
    uint64_t a;
    uint8_t b[8];
};

but we cannot declare std::variant like this(please do not care about syntax,correct me if I am wrong!, just grab the idea)

std::variant<uint64_t, uint8_t[8]> v

cppReference stated clearly that,

Template parameters

Types - the types that may be stored in this variant. All types must be (possibly cv-qualified) non-array object type

also,MSVC-v141(C++17) compiler has given a compilation error:

Error C2338 variant requires all of the Ts to be non-array object types ([variant.variant]/2).


std::variant is primarily a class template hence, Problem is it unable to deduce array type storage, since it requires only data layout/representation ?

like image 468
Buddhika Chaturanga Avatar asked Mar 15 '18 05:03

Buddhika Chaturanga


1 Answers

Support for arrays was removed in P0510R0 after national body comment US116, which I reproduce below:

Support for array alternatives does not seem to work as expected. For example, if any of the alternatives is an array, the current specification fails to satisfy the Requires clause for all 6 relational operators, and loses (shall not participate in overload resolution) the copy constructor, move constructor, copy-assignment operator, move-assignment operator (although the swap functions will work correctly). It is difficult to activate an array alternative - to the best of my understanding, it must be emplaced with no arguments in order to value-initialize the array, and then the value of each element may be assigned as needed. Many of these issues would be resolved if array alternatives were implemented by storing a std::array instead, and then exposing the exposition-only array member (of the std::array) to the get functions, but that seems like an experimental change that should be investigated for the next standard. For C++17, we should drop support for arrays (but not std::array) as alternatives, in order to leave freedom to support them properly in the next standard.

It seems likely that during the initial revisions of the std::variant proposal, not much thought was given to the possibility of array types, although some thought was given to the case of reference and void types (support for these was also removed in P0510R0), and some of the revisions implicitly forbade arrays by imposing the Destructible requirement (which is not present in the final standard text). Once the draft standard was sent out to the national member bodies, someone noticed that arrays pose difficulties because they cannot be copied, moved, or compared in the expected fashion. All of these issues could, perhaps, be solved by special-casing arrays in the specification and implementation (member-wise comparison, etc.), but this work was left for a future revision of the standard.

like image 178
Brian Bi Avatar answered Oct 14 '22 06:10

Brian Bi