C++11 move constructor for union-like class
No, there is no better way. If you want to safely move from a union containing arbitrary types, you must do so from the field of the union that has last been written to (if any). The other answer stating the contrary is wrong, consider an example like
union SomethingLikeThisIsGoingToHappenInPractice {
std::string what_we_actually_want_to_move;
char what_we_do_not_care_about[sizeof(std::string)+1];
};
If you use the move constructor of the 'largest' type here you'd have to pick the char
array here, despite moving that actually not really doing anything. If the std::string
field is set you'd hope to move its internal buffer, which is not going to happen if you look at the char
array. Also keep in mind that move semantics is about semantics, not about moving memory. If that was the issue you could just always use memmove
and be done with it, no C++11 required.
This isn't even going into the problem of reading from a union member you haven't written to being UB in C++, even for primitive types but especially for class types.
TL;DR if you find yourself in this situation use the solution originally proposed by the OP, not what's in the accepted answer.
PS: Of course if you are just moving a union that only contains things that are trivially moveable, like primitive types, you could just use the default move constructor for unions which does just copy the memory; In that case it's really not worth it to have a move constructor in the first place though, other than for consistencies sake.