2010-06-13 22 views
13

Estoy tratando de inicializar estáticamente la siguiente estructura en Visual Studio 2010:inicializar estáticamente unión anónima en C++

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

El siguiente es un error con error C2440: 'initializing' : cannot convert from 'Data *' to 'char'.

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

He encontrado referencias a algunas formas en que se puede inicializar correctamente, pero ninguna de ellas funciona en VS2010. ¿Algunas ideas?

Respuesta

5

¿Puedes hacerlo definiendo constructores sobrecargados? código no probado por delante:

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); 
+0

Gracias! Hice esto en una solución viable. – wpfwannabe

2

Cambiar a:

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

static Data d1; 
static Data d = {1, &d1}; 
+0

hecho de que funciona, pero he simplificado mi caso de la vida real por lo que ahora he actualizado a la pregunta con un código mejor qué falla por 'd2' inicialización – wpfwannabe

+0

Me imagino que no es evidente para los recién llegados por qué se supone que esto funciona. Siempre agrego una pequeña explicación a mis respuestas de este tipo. –

24

ISO C++ 03 8.5.1 [dcl.init.aggr]/15:

Cuando una unión se inicia con un inicializador corsé-cerrado , las llaves solo contendrán un inicializador para el primer miembro de la unión. [Ejemplo:

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 ejemplo]

Así, hablando en general, no puede ser hecho.

+0

¡Muchas gracias! Temía que esa sería la respuesta. +1 voto por usted, pero responda a "ChrisW" para una solución utilizable. – wpfwannabe

1

Usted puede hacer este trabajo si todos los tipos de unión son punteros, mediante el uso de un puntero nulo como el primer elemento de la unión. Todos los punteros se pueden convertir en un puntero de vacío, por lo que su unión se puede inicializar con un tipo de puntero arbitrario. Para el ejemplo dado, obtienes:

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!"}; 

La otra posibilidad es hacer esto en C en su lugar. En C puede especificar qué parte de la unión se inicializa. Usando su estructura original (y dando a su estructura el nombre asStruct):

static Data d1; 
static Data d2 = {2, &d1}; 
static Data d3 = {3, {.asStruct = {0,0}} 
Cuestiones relacionadas