Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ casting a union to one of its member types

The following seems perfectly logical to me, but isn't valid c++. A union cannot be implicitly cast to one of it's member types. Anyone know a good reason why not?

union u {
  int i;
  char c;
}
function f(int i) {
}
int main() {
  u v;
  v.i = 6;
  f(v);
}

And can anyone suggest a clean alternative (the cleanest I can come up with is f(v.i);, which I admit is very clean, but the above just seems even cleaner)

like image 558
Baruch Avatar asked Feb 20 '11 21:02

Baruch


People also ask

How are casting and unions related?

6.31 Cast to a Union TypeThe result of a cast to a union is a temporary rvalue of the union type with a member whose type matches that of the operand initialized to the value of the operand. The effect of a cast to a union is similar to a compound literal except that it yields an rvalue like standard casts do.

Can I have static members in an union?

In C++ union can contain static members which, as in the case of classes, belong to a class and therefore are common to all objects.

What is union Data Type C++?

In C++17 and later, the std::variant class is a type-safe alternative for a union. A union is a user-defined type in which all members share the same memory location. This definition means that at any given time, a union can contain no more than one object from its list of members.


2 Answers

While agreeing with Crazy Eddie that it doesn't look that better to me you can actually get an implicit conversion by defining it:

union u {
    int i;
    char c;
    operator int () const { return i; }
    operator char () const { return c; }
};
like image 172
6502 Avatar answered Oct 18 '22 18:10

6502


How would the compiler know which member to use? It would need to keep track of which member was last assigned so it knows what to convert to. This is called a tagged union, and while it's certainly possible for the language to specify such a thing, that's not the case (it's a hold-over from C).

But that's okay, because we have boost::variant. Not only is it safer and more flexible than a union, it's more powerful. You can apply visitors to the variant, and it'll call (visit) the specified function with whichever member is currently active, with no further work from the user.

like image 43
GManNickG Avatar answered Oct 18 '22 17:10

GManNickG