C++ does not generally go out of its way to encourage the use of unions, and it can be particularly awkward if union members have non-trivial constructors and destructors, since in that case the union's own constructor (destructor, respectively) will be deleted and you'll have to provide one yourself if you need one (which you generally do).
On the whole, it's probably not a great idea to put non-POD types into a union, since the semantics are awkward; in general, you cannot assign a value to an object which has not been constructed, and, while you could use placement new to construct a member of a union, you would have no way to actually know that the member hadn't been previously constructed. Furthermore, if a member has an explicit and non-trivial destructor, you could provide an explicit destructor for the union, which could explicitly call the member's destructor, but how would it know whether it had to do that or not?
If your union members are POD, though, you're fine, but you still cannot cast the union to a member or a member type to the union. (GCC allows this as a C extension, but afaik g++
does not extend C++ in the same way.)
Still, there is nothing stopping you from giving the union
a constructor. For example:
union long_or_double {
long a;
double d;
long_or_double(long l) : a(l) {}
long_or_double(int i) : a(i) {}
// etc.
long_or_double(double d) : d(d) {}
};
int f(long_or_double u);
int main(int argc, char** argv) {
// Both of these work, because there is an explicit constructor
f(argc);
f(3.7);
// ...
}
If you cannot add constructors to the definition of the union type, I think the best you can do is to define a make_union
function, overriding it appropriately for each member type.