Esto parece un error tipográfico simple, pero la situación es lo suficientemente compleja como para abordarlo paso a paso.
Primero déjame mostrarte la solución que parece funcionar:
int main()
{
str t[2] = { { { {0, 2}, {4, 6} } }, { { {1, 3}, {5, 7} } } };
cout << t[1].t[0].t[1] << t[0].t[1].t[0] << endl;
return 0;
}
Entonces tenemos una matriz de str
que contiene una matriz de sct
.
Comencemos con el último. Inicializa una matriz de sct
con algo como esto:
sct x[2] = { {0, 1}, {2, 3} };
Ahora, para una sola instancia de str
usted podría ir con
str y = { { {0, 2}, {4, 6} } };
Lo que queda str t[2]
es organizar dos copias de las str
expresiones de inicialización entre llaves:
str t[2] = { { { {0, 2}, {4, 6} } }, { { {1, 3}, {5, 7} } } };
Editado: en la primera lectura no entendí la pregunta. Después de que se actualizó la publicación, quedó claro que la pregunta es por qué es posible arrojar dos pares de llaves, pero arrojar solo un par da como resultado un error de sintaxis.
Para comprender cómo interpreta el analizador el código, puede que desee mirar el árbol de análisis. Puede hacer gcc dump trees en varias etapas del analizador con -fdump-tree-...
opciones. Aquí -fdump-tree-original
puede ser útil.
Para evitar confusiones adicionales, asegurémonos de que los elementos de las estructuras tengan nombres diferentes:
struct sct
{
int a[2];
};
struct str
{
sct b[2];
};
Aquí está la salida que obtuve con GCC 7.5 de
>>>> CODE:
str t[2] = { { 0, 2, 4, 6 }, { 1, 3, 5, 7 } };
>>>> tree enabled by -tree-original
struct str t[2] = {{.b={{.a={0, 2}}, {.a={4, 6}}}}, {.b={{.a={1, 3}}, {.a={5, 7}}}}};
Puede ver que el compilador agrega corchetes implícitos alrededor de las expresiones de inicialización para cada estructura y alrededor de las expresiones de inicialización para cada campo con nombre.
Ahora considere la expresión que no se compila:
str t[2] = { { {0, 2},{4, 6} }, { {1, 3},{5, 7} } };
A el nivel superior, el árbol para esta expresión sería
/*Step 1: */ struct str t[2] = { {.b={0, 2}, {4, 6} }, {.b={1, 3}, {5, 7} } };
Pero a medida que b es un vector de sct
, tratamos de que inicializar con {0,2}
conseguir
sct b[2] = {0, 2};
Esto se expande a
struct sct b[2] = {{.a={0, 2} }};
Esto es válido en C ++ ya que el primer elemento de la matriz se inicializa explícitamente y el segundo elemento se inicializa implícitamente con ceros.
Con este conocimiento obtenemos el siguiente árbol
/*Step 2: */ struct str t[2] = { {.b={{.a={0, 2} }}, {4, 6} }, {.b={{.a={1, 3} }}, {5, 7} } };
Ahora nos queda lo siguiente:
struct str z = { { { {0,2} }, { {0,0} } }, {4, 6} };
Y el compilador se queja legítimamente:
error: too many initializers for ‘str’
Como verificación final, considere la siguiente declaración
struct sxc
{
sct b[2];
int c[2];
}
struct sxc z = { {0,2} , {4, 6} };
Esto compila y da como resultado la siguiente estructura:
{ .b = { { .a={0,2} }, { .a={0,0} } }, .c={4, 6} }