views:

56

answers:

4
class Foo {
    Foo(int val) { /* Do some initialization */ }
    Foo() { /* Do nothing */ }
};
union Bar {
    Foo foo;
};

That code generates this error:

error C2620: member 'Bar::foo' of union 'Bar' has user-defined constructor or non-trivial default constructor

I understand why you'd throw that error if the constructor actually did something, but the constructor here takes no parameters and does nothing. Is there any way I can stuff this class into a union? I've had to resort all the way to doing char foo[sizeof(Foo)] and would like a cleaner solution.

+1  A: 

Standard-specialists will likely answer this question more precisely than I do, but if I recall correctly, union members must be of POD type.

Use boost::variant if you want to use non-POD classes inside a union.

Alexandre C.
+3  A: 

Originally from this question:

http://stackoverflow.com/questions/321351/initializing-a-union-with-a-non-trivial-constructor:

From C++03, 9.5 Unions, pg 162

A union can have member functions (including constructors and destructors), but not virtual (10.3) functions. A union shall not have base classes. A union shall not be used as a base class.An object of a class with a non-trivial constructor (12.1), a non-trivial copy constructor (12.8), a non-trivial destructor (12.4), or a non-trivial copy assignment operator (13.5.3, 12.8) cannot be a member of a union, nor can an array of such objects

So, your class is forbidden to be a member of the union.

LaszloG
A: 

If your class has a user defined constructor, destructor or copy constructor, or assignment operator then it cannot be inside of a Union.

C Johnson
A: 

This isn't allowed in the C++03 standard.

If objects with user defined default constructors were allowed in a union, the compiler couldn't decide which constructor to use, because all refer to the same memory location. Thus, objects with user defined constructors aren't allowed in unions.

The compiler will ignore the fact that your constructor doesn't do anything, because it might be defined elsewhere than the union.

You might get away with a C++0x constructor() = default;

drhirsch
That's a shame ... if I only use "Foo() = default" it works, but if I add another constructor along with the explicit default it complains again.
Chris