Статически инициализировать анонимный союз в С++
Я пытаюсь статически инициализировать следующую структуру в Visual Studio 2010:
struct Data
{
int x;
union
{
const Data* data;
struct {int x; int y; };
};
};
Сбой <<21 > не работает.
static Data d1;
static Data d = {1, &d1};
static Data d2 = {1, {1, 2}};
Я нашел ссылки на некоторые способы, которые могут быть правильно инициализированы, но ни один из них не работает в VS2010. Любые идеи?
Ответы
Ответ 1
Можете ли вы это сделать, указав перегруженные конструкторы? Непросроченный код впереди:
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);
Ответ 2
ISO С++ 03 8.5.1 [dcl.init.aggr]/15:
Когда объединение инициализируется с помощью инициализатора, заключенного в фигурные скобки, фигурные скобки должны содержать только инициализатор для первого члена объединения. [Пример:
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 пример]
Итак, вообще говоря, это невозможно.
Ответ 3
Измените его на:
struct Data
{
int x;
union
{
const Data* data;
char ch;
};
};
static Data d1;
static Data d = {1, &d1};
Ответ 4
Вы можете выполнить эту работу, если все ваши типы соединений являются указателями, используя указатель void как первый элемент объединения. Все указатели могут быть преобразованы в указатель void, поэтому ваш союз можно инициализировать с помощью произвольного типа указателя. В данном примере вы получите:
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!"};
Другая возможность заключается в том, чтобы сделать это вместо C. В C вы можете указать, какая часть объединения инициализирована. Используя вашу исходную структуру (и придав вашей структуре имя asStruct):
static Data d1;
static Data d2 = {2, &d1};
static Data d3 = {3, {.asStruct = {0,0}}