Me encontré con este ejemplo
struct sct
{
int t[2];
};
struct str
{
sct t[2];
};
int main()
{
str t[2] = { {0, 2, 4, 6}, {1, 3, 5, 7} }; //Who does this work?
cout << t[1].t[0].t[1] << t[0].t[1].t[0];
return 0;
}
Esto compila y funciona bien. Da la salida34
Esperaba que la sintaxis para la inicialización fuera:
str t[2] = { { {0, 2},{4, 6} }, { {1, 3},{5, 7} } };
En vez de
{ {0, 2, 4, 6}, {1, 3, 5, 7} };
Pero esto dio:
In function 'int main()':
error: too many initializers for 'str'
¿Alguien puede explicar por qué?
Esta es una imagen para ilustrar la forma en que veo esto:
¿Cómo debo pensar cuando se trata de inicializar estructuras anidadas?
c++
struct
nested
uniform-initialization
Cătălina Sîrbu
fuente
fuente
Respuestas:
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:
Entonces tenemos una matriz de
str
que contiene una matriz desct
.Comencemos con el último. Inicializa una matriz de
sct
con algo como esto:Ahora, para una sola instancia de
str
usted podría ir conLo que queda
str t[2]
es organizar dos copias de lasstr
expresiones de inicialización entre llaves: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:
Aquí está la salida que obtuve con GCC 7.5 de
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:
A el nivel superior, el árbol para esta expresión sería
Pero a medida que b es un vector de
sct
, tratamos de que inicializar con{0,2}
conseguirEsto se expande a
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
Ahora nos queda lo siguiente:
Y el compilador se queja legítimamente:
Como verificación final, considere la siguiente declaración
Esto compila y da como resultado la siguiente estructura:
fuente
str t[2] = { {0, 2, 4, 6}, {1, 3, 5, 7} }
? Veo que el compilador los asume en orden. Desde la última línea de tu respuesta, ¿cómo modificarías para llegar a esta{ {0, 2, 4, 6}, {1, 3, 5, 7} }
?{ }
)?"sct.t
ystr.t
desct.a
ystr.b
, respectivamente. Ahí es donde.a
y.b
vienen.