Remove two-phase initialization for union types
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.
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.
After discussion in #555 and regarding to #444 it seems that strong typedefs will fit better.