2014-12-27 19 views

risposta

17

Aggiungi un altro paio di parentesi graffe.

std::array<std::pair<int, int>, 2> ids = { { { 0, 1 }, { 1, 2 } } }; 

std::array<T, N> è una classe aggregata di un membro di tipo T[N]. Di solito, è possibile inizializzarlo allo stesso modo in cui si utilizza un semplice array T[N], ma quando si ha a che fare con un tipo di elemento non aggregato, potrebbe essere necessario essere più espliciti.

+0

Questo sembra spiegare tutto, finché non guardi la risposta di Joachim usando 'std :: make_pair'. Come funziona _that_, senza il paio di parentesi graffe aggiuntive? – TonyK

+0

@TonyK In generale, le parentesi possono essere omesse. 'int a [2] [2] = {0, 1, 2, 3};' è perfettamente valido. Ma quando hai a che fare con classi con costruttori forniti dall'utente, le cose diventano un po 'complicate: '{0, 1}' potrebbe essere un tentativo di inizializzare il primo elemento, o il primo elemento secondario. L'ambiguità è risolta in favore del primo elemento. D'altra parte, il risultato di 'make_pair' può essere utilizzato solo per inizializzare il primo elemento secondario. – hvd

+0

L'unica cosa che lo standard garantisce di funzionare è "' array a = {initializer-list}; 'dove * initializer-list * è un elenco separato da virgola di elementi fino a' N' i cui tipi sono convertibili in 'T' ". La coppia extra di parentesi graffe probabilmente funzionerà su tutte le implementazioni correnti, ma non è garantita. –

13

std::array è un aggregato. Ha un solo membro di dati - una matrice del tipo specificato della specializzazione std::array. Secondo lo standard C++. (8.5.1 Aggregati)

2 When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list are taken as initializers for the members of the aggregate, in increasing subscript or member order

Così questo disco

std::array<std::pair<int, int>, 2> ids = { { 0, 1 }, { 1, 2 } }; 

ha più inizializzatori poi ci sono membri di dati in std :: array.

Il membro di dati di std::array è a sua volta un aggregato. Devi fornirgli una lista di inizializzazione.

modo che il record sarà simile

std::array<std::pair<int, int>, 2> ids = { { { 0, 1 }, { 1, 2 } } }; 

Perché sarebbe più chiaro si può immaginare l'inizializzazione seguente modo

std::array<std::pair<int, int>, 2> ids = { /* an initializer for data member of the array */ }; 

Come membro dati è aggregato allora devi scrivere

std::array<std::pair<int, int>, 2> ids = { { /* initializers for the aggregate data member*/ } }; 

E infine

std::array<std::pair<int, int>, 2> ids = { { { 0, 1 }, { 1, 2 } } }; 
+2

Se si utilizza lo standard, non è possibile garantire che 'std :: array' abbia un solo membro di dati. –

+0

@ T.C. Senza queste informazioni non è possibile inizializzare correttamente la matrice. Almeno per l'esposizione lo standard include nella definizione dell'array il seguente membro di dati T elems [N]; –

+0

Lo standard garantisce che 'array a = {initializer-list};' funzionerà se l'elenco di inizializzazione contiene fino a N elementi ciascuno di un tipo convertibile in 'T'. Non c'è alcuna garanzia che l'array integrato (se usato - non so se è possibile soddisfare tutti i requisiti senza usarne uno) è l'unico membro di dati. –

Problemi correlati