zserio icon indicating copy to clipboard operation
zserio copied to clipboard

Remove two-phase initialization for union types

Open MikeLankamp-TomTom opened this issue 2 years ago • 2 comments

Union types are turned into Any types in C++ (basically std::any). However, these must be constructed via two-phase initialization:

union SimpleUnion
{
    uint8   value8;
    uint16  value16;
};

becomes

SimpleUnion val;
val.setValue8(42);

It is more inline with modern C++ practices to allow inline creation of these unions, for instance via any of the following forms:

const auto val = SimpleUnion(SimpleUnion::value8{}, 42); // tag-based construction
const auto val = SimpleUnion::create_value8(42); // static factory method
const auto val = SimpleUnion(SimpleUnion::value8{42}); // strong typedef

Similarly, zserio could adopt std::any's approach fully and also support accessing it via e.g. val.get<SimpleUnion::value8>();, which combines well with the tag-based or strong typedef approach above.

MikeLankamp-TomTom avatar Dec 14 '23 19:12 MikeLankamp-TomTom

Thanks for posting the issue. Current solution was chosen for simplicity and it should be possible to improve unions and probably also choices constructors. I like the tag-based solution most since we already use some tags elsewhere. We can consider also the generic getter with tags.

We should consider how to deal with compound types members - whether to support only perfect forwarding constructors or also some kind of inplace constructor.

Mi-La avatar Dec 15 '23 09:12 Mi-La

After discussion in #555 and regarding to #444 it seems that strong typedefs will fit better.

Mi-La avatar Dec 15 '23 10:12 Mi-La