Questions regarding C++ non-POD unions
Asked Answered
M

3

13

C++11 gave us to possibility to use non-POD types within unions, say I have the following piece of code;

union
{
    T one;
    V two;
} uny;

Somewhere within my class, only one member will be active at a time, now my questions are rather simple.

  1. What is the default value of uny? - undefined?
  2. Whenever my class is destructed, which members (within the union), if any will be destructed?
    • Suppose I have to std::typeinfo to keep track of which is the active member, should I then call the destructor explicitly on that member in the destructor?
  3. Does anyone have a link to the language proposal, which changed unions to accept non-POD types?
Mutinous answered 4/11, 2013 at 8:42 Comment(1)
This answer has details about how to actually do this.Unstop
N
16

You're mostly on your own. A note in the standard explains this (9.5/2):

If any non-static data member of a union has a non-trivial default constructor (12.1), copy constructor (12.8), move constructor (12.8), copy assignment operator (12.8), move assignment operator (12.8), or destructor (12.4), the corresponding member function of the union must be user-provided or it will be implicitly deleted (8.4.3) for the union.

So if any of the member constructors are non-trivial, you need to write a constructor for the union (if they are all trivial, the default state will be uninitialized, like for union { int; double; }). If any members have a destructor, you need to write a destructor for the union which must take care of figuring out the active element.

There's a further note (9.5/4) about typical usage of an unconstrained union:

In general, one must use explicit destructor calls and placement new operators to change the active member of a union.

Noontime answered 4/11, 2013 at 9:10 Comment(1)
can u clarify what standard specifies that? C++11 or regular C++?Towrey
E
1

Alternatives to union:

std::any / std::variant (C++17)

boost::any / boost::variant

These allow to use non-POD data types.

Enameling answered 11/10, 2016 at 11:13 Comment(7)
This is a very clearly-written (and 3-years-old) question asking about the behaviours of unions with non-POD types. How does naming some alternatives answer the question?Bugaboo
@ChrisH - Because alternatives can provide a better solution. It allows the possibility to compare the behavior of unions against new modern features, designed to deal with non-POD data types. And I do not understand your point about the fact that this question is 3 years old; if it can be seen now, in 3 or 30 years time, shouldn't it be worth of any update? RSVPEnameling
The post asks very specific questions about how a union with non-POD types behaves. If you were to illustrate how the alternatives compare, you'd be contributing something relevant to the question. As it is, you've answered a "how does x work" question with "you could use y instead". That's objectively not answering the questions asked. Even if they had asked for alternatives, this wouldn't be a good answer. Simply naming alternatives with no comparison of their functionality is of little benefit to anyone.Bugaboo
As for the timing issue, I fully agree that adding good answers to old questions is valuable. But when they're answers to an entirely different question than was asked, and not even particularly good answers to that one... it's a rather different story.Bugaboo
@ChrisH - I suppose we are all able to find documentation about C++ features quite easily on our own. So in my answer I just give a suggestion, pointing to an alternative option that can deal with non-POD data types. AKAIK, on StackOverflow such a kind of information is not simple white noise, and who is interested, with a couple of mouse-clicks, can find everything he needs. Here we do not necessarily have to rewrite everything, a link can be enough.Enameling
if you want to provide additional information that you feel is relevant despite not being an answer, you can do so in a comment. Stack Overflow answers are expected to answer the question.Bugaboo
All of the solutions you're referring to use a union internally. std::variant use a recursive variadic union. So it does not answer the question, but they are not an "alternative" since they do exactly what the OP is asking for. The answer would be better if you linked to the source code of one of the solution to explain how it's doneGravely
S
0

It's a tricky question.

may be you can use this:

uny un;
new(&un.one) T;

You can refer to https://en.cppreference.com/w/cpp/language/union

Shrinkage answered 2/11, 2021 at 11:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.