I start playing with unions and run into trouble by compiling a simple example from a c++11 FAQ. The results are discussed here:
c++11 unrestricted unions example
No I play around with some more code:
Example Code 1:
class A
{
private: int a;
public:
A(): a(0) { cout << "Create A no args" << endl; }
};
class B
{
private: float b;
public:
};
class OneOfN
{
public:
union U
{
A a;
B b;
} u;
};
OneOfN n{}; // Compiles! That I did not expect, but the constructor will not be
// called! But why?
To make the things a bit more strange here comes example 2 with two union members where no one has a default constructor! And the union itself has also no constructor provided but it compiles and works as expected. Wow!
Exmaple 2:
class A
{
private: int a;
public:
A(int _a): a(_a) { cout << "Create A with args" << endl; }
};
class B
{
private: float b;
};
class OneOfN
{
public:
union U
{
A a;
B b;
} u;
};
int main()
{
OneOfN n2{1}; // This compiles as expected, constructor A(int) is called! Fine!
// But we see later, this is not the truth!
};
Question: If the code of example 2 is valid, why there is there no chance to use the given default constructor for a member of a union? Using the constructor with parms looks ok and works as expected. Strange to me!
Continue this mystery and addapt the example to have one more data member in class A we run into trouble. See example 3:
class A
{
private:
int a;
int aa;
public:
A( int _a, int _aa): a(_a), aa(_aa) { cout << "Create with 2 args" << endl; }
};
class B
{
private: float b;
public:
};
class OneOfN
{
public:
union U
{
A a;
B b;
} u;
};
int main()
{
OneOfN n3{2,3}; // Ups! Fails
};
Ups! Now we see that the creation of an instance of OneOfN fails. What happens?
As written in example2, it is not the the constructor A(int) which is called! It is a two step init! First create a A with call to A(int) and then give that object to the copy constructor!
As a result of this, the following change to example 3 makes the example working:
OneOfN n4{A{2,3}}; // Works! Ah! We use implicit the copy construction!
Question:
1) Is this code valid?
2) Why the copy constructor works but default constructors did not? For me as user it looks really strange.
3) Is it true that always, if no default constructor to the union is manually written, the argument to the constructor for the union will passed to the copy constructor of the FIRST union element?
My intention to give this three step example is that you can catch my ideas. As a result I hope this example give a hint for the correct usage of 'unrestricted unions' for other beginners :-) For me the behavior looks very special.