user1849534
user1849534

Reputation: 2407

A well supported alternative to c++ unions?

I think that unions can be perfect for what i have in mind and especially when I consider that my code should run on a really heterogeneous family of machines, especially low-powered machine, what is bugging me is the fact that the people who creates compilers doesn't seem to care too much about introducing and offering a good union support, for example this table is practical empty when it comes to Unrestricted Unions support, and this is a real unpleasant view for my projects.

There are alternatives to union that can at least mimic the same properties ?

Upvotes: 3

Views: 9956

Answers (3)

Öö Tiib
Öö Tiib

Reputation: 10979

One popular alternative to union is Boost.Variant.

The types you use in it have to be copy-constructible.

Update: C++17 introduced std::variant. Its requirements are based on Boost.Variant. It is modernized to take into account the features in C++17. It does not carry the overhead of being compatible with C++98 compilers (like Boost). It comes for free with standard library. If available it is better to use it as alternative to unions.

Upvotes: 6

Lie Ryan
Lie Ryan

Reputation: 64837

Union is well supported on most compilers, what's not well supported are unions that contains members that have non trivial constructor (unrestricted unions). In practice, you'd almost always want a custom constructor when creating unions, so not having unrestricted union is more of a matter of inconvenience.

Alternatively, you can always use void pointer pointing to a malloc-ed memory with sufficient size for the largest member. The drawback is you'd need explicit type casting.

Upvotes: 9

Yakov Galka
Yakov Galka

Reputation: 72479

You can always do essentially the same thing using explicit casts:

struct YourUnion {
    char x[the size of your largest object];
    A &field1() { return *(A*)&x[0]; }
    int &field2() { return *(int*)&x[0]; }
};

YourUnion y;
new(&y.field1()) A(); // construct A
y.field1().~A(); // destruct A
y.field2() = 1;
// ...

(This is zero overhead compared to, e.g., Boost.Variant.)

EDIT: more union-like and without templates.

Upvotes: 3

Related Questions