I am trying to statically initialize the following structure in Visual Studio 2010:
struct Data
{
int x;
union
{
const Data* data;
struc
Can you do it by defining overloaded constructors? Untested code ahead:
struct Data
{
int x;
union
{
const Data* data;
struct {int a; int b; } z;
} y;
Data()
{
x = 0;
y.data = 0;
y.z.a = 0;
y.z.b = 0;
}
Data(int x_, Data* data_)
{
x = x_;
y.data = data_;
}
Data(int x_, int a_, int b_)
{
x = x_;
y.z.a = a_;
y.z.b = b_;
}
};
static Data d1;
static Data d(1, &d1);
static Data d2(1, 1, 2);
ISO C++03 8.5.1[dcl.init.aggr]/15:
When a union is initialized with a brace-enclosed initializer, the braces shall only contain an initializer for the first member of the union. [Example:
union u { int a; char* b; }; u a = { 1 }; u b = a; u c = 1; // error u d = { 0, "asdf" }; // error u e = { "asdf" }; // error
—end example]
So, generally speaking, it can't be done.
You can make this work if all your union types are pointers, by using a void pointer as the first element of the union. All pointers can be converted to a void pointer, so your union can be initialized with an arbitrary pointer type. For the given example, you get:
struct Data
{
int x;
union
{
const void* unused;
const Data* data;
struct {int x; int y; }*; //Not sure this works written like this
const char* asChar;
const int* asInt;
};
};
static Data d1;
static Data d2 = {2, &d1};
static Data d3 = {1, "Hello, world!"};
The other possibility is to do this in C instead. In C you can specify which part of the union is initialized. Using your original struct (and giving your structure the name asStruct):
static Data d1;
static Data d2 = {2, &d1};
static Data d3 = {3, {.asStruct = {0,0}}
Change it to:
struct Data
{
int x;
union
{
const Data* data;
char ch;
};
};
static Data d1;
static Data d = {1, &d1};