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:
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;
}
Portanto, temos uma variedade de str
que contém uma matriz de sct
.
Vamos começar com o último. Você inicializa uma matriz desct
algo como isto:
sct x[2] = { {0, 1}, {2, 3} };
Agora, para uma única instância de str
você poderia ir com
str y = { { {0, 2}, {4, 6} } };
O que resta str t[2]
é organizar duas cópias das str
expressões de inicialização entre colchetes:
str t[2] = { { { {0, 2}, {4, 6} } }, { { {1, 3}, {5, 7} } } };
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:
struct sct
{
int a[2];
};
struct str
{
sct b[2];
};
Aqui está a saída que obtive com o 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}}}}};
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:
str t[2] = { { {0, 2},{4, 6} }, { {1, 3},{5, 7} } };
No nível superior, a árvore para esta expressão seria
/*Step 1: */ struct str t[2] = { {.b={0, 2}, {4, 6} }, {.b={1, 3}, {5, 7} } };
Mas como b é uma matriz de sct
, tentamos inicializar isso com a {0,2}
obtenção de
sct b[2] = {0, 2};
Isso se expande para
struct sct b[2] = {{.a={0, 2} }};
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
/*Step 2: */ struct str t[2] = { {.b={{.a={0, 2} }}, {4, 6} }, {.b={{.a={1, 3} }}, {5, 7} } };
Agora ficamos com o seguinte:
struct str z = { { { {0,2} }, { {0,0} } }, {4, 6} };
E o compilador reclama com razão:
error: too many initializers for ‘str’
Como verificação final, considere a seguinte declaração
struct sxc
{
sct b[2];
int c[2];
}
struct sxc z = { {0,2} , {4, 6} };
Isso compila e resulta na seguinte estrutura:
{ .b = { { .a={0,2} }, { .a={0,0} } }, .c={4, 6} }