Статическая инициализация анонимного объединения в C ++ - PullRequest
13 голосов
/ 13 июня 2010

Я пытаюсь статически инициализировать следующую структуру в Visual Studio 2010:

struct Data
{
   int x;
   union
   {
      const Data* data;
      struct {int x; int y; };
   };
};

Следующее не работает с error C2440: 'initializing' : cannot convert from 'Data *' to 'char'.

static Data d1;
static Data d = {1, &d1};
static Data d2 = {1, {1, 2}};

Я нашел ссылки на некоторые способы правильной инициализации, но ни один из них не работает в VS2010. Есть идеи?

Ответы [ 4 ]

24 голосов
/ 13 июня 2010

ISO C ++ 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

- конец примера]

Так что, вообще говоря, это невозможно сделать.

5 голосов
/ 13 июня 2010

Можете ли вы сделать это путем определения перегруженных конструкторов?Непроверенный код впереди:

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 голосов
/ 13 июня 2010

Измените его на:

struct Data
{
   int x;
   union
   {
      const Data* data;
      char ch;
   };
};

static Data d1;
static Data d = {1, &d1};
1 голос
/ 25 марта 2011

Вы можете сделать это, если все ваши типы объединений являются указателями, используя указатель 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}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...