Me deparei com este exemplo
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;
}
Isso compila e funciona bem. Dá a saída34
Eu esperava que a sintaxe para inicialização fosse:
str t[2] = { { {0, 2},{4, 6} }, { {1, 3},{5, 7} } };
Ao invés de
{ {0, 2, 4, 6}, {1, 3, 5, 7} };
Mas isso deu:
In function 'int main()':
error: too many initializers for 'str'
Alguém pode explicar o porquê?
Esta é uma figura para ilustrar a maneira como vejo isso:
Como devo pensar quando se trata de inicializar estruturas aninhadas?
c++
struct
nested
uniform-initialization
Cătălina Sîrbu
fonte
fonte
Respostas:
Parece um erro de digitação simples, mas a situação é complexa o suficiente para lidar com isso passo a passo.
Primeiro, deixe-me mostrar a solução que parece funcionar:
Portanto, temos uma variedade de
str
que contém uma matriz desct
.Vamos começar com o último. Você inicializa uma matriz de
sct
algo como isto:Agora, para uma única instância de
str
você poderia ir comO que resta
str t[2]
é organizar duas cópias dasstr
expressões de inicialização entre colchetes:Editado: Na primeira leitura, eu entendi mal a pergunta. Após a atualização da postagem, ficou claro que a pergunta é por que é possível lançar dois pares de chaves, mas eliminar apenas um par resulta em um erro de sintaxe.
Para entender como o analisador está interpretando o código, você pode olhar para a árvore de análise. Você pode fazer o dump de árvores do gcc em vários estágios do analisador com
-fdump-tree-...
opções. Aqui-fdump-tree-original
pode ser útil.Para evitar confusão adicional, verifique se os elementos das estruturas têm nomes diferentes:
Aqui está a saída que obtive com o GCC 7.5 de
Você pode ver que o compilador adiciona colchetes implícitos em torno das expressões de inicialização para cada estrutura e em torno das expressões de inicialização para cada campo nomeado.
Agora considere a expressão que falha ao compilar:
No nível superior, a árvore para esta expressão seria
Mas como b é uma matriz de
sct
, tentamos inicializar isso com a{0,2}
obtenção deIsso se expande para
Isso é válido em C ++, pois o primeiro elemento da matriz é inicializado explicitamente e o segundo elemento é inicializado implicitamente com zeros.
Com esse conhecimento, obtemos a seguinte árvore
Agora ficamos com o seguinte:
E o compilador reclama com razão:
Como verificação final, considere a seguinte declaração
Isso compila e resulta na seguinte estrutura:
fonte
str t[2] = { {0, 2, 4, 6}, {1, 3, 5, 7} }
. Vejo que o compilador as assume em ordem. A partir da última linha de sua resposta, como você modificaria para chegar a esta{ {0, 2, 4, 6}, {1, 3, 5, 7} }
?{ }
)?"sct.t
estr.t
parasct.a
estr.b
respectivamente. É daí.a
e de onde.b
veio.