2012-10-11 11 views
16

Possible Duplicate:
c++ why initializer_list behavior for std::vector and std::array are differentPerché non è possibile inizializzare in modo semplice (con parentesi) 2D std :: array?

ho definito semplice array 2D (3X2):

std::array<std::array<int,3>,2> a { 
    {1,2,3}, 
    {4,5,6} 
    }; 

Mi ha sorpreso questa inizializzazione non funziona, con l'errore gcc4.5: too many initializers for 'std::array<std::array<int, 3u>, 2u>'

Perché non posso usare questo sintassi?

Ho trovato soluzioni alternative, una molto divertente con parentesi graffe aggiuntive, ma mi chiedo solo perché il primo approccio, più semplice, non è valido?

Soluzioni alternative:

// EXTRA BRACES 
    std::array<std::array<int,3>,2> a {{ 
    {1,2,3}, 
    {4,5,6} 
    }}; 

    // EXPLICIT CASTING 
    std::array<std::array<int,3>,2> a { 
    std::array<int,3>{1,2,3}, 
    std::array<int,3>{4,5,6} 
    }; 

[UPDATE]

Ok, grazie a KerrekSB e commenti ottengo la differenza. Così sembra che non ci sia troppo poco parentesi nel mio esempio, come in questo esempio C:

struct B { 
    int array[3]; 
}; 
struct A { 
    B array[2]; 
}; 

B b = {{1,2,3}}; 
A a = {{ 
    {{1,2,3}}, 
    {{4,5,6}} 
}}; 
+0

'std :: array' è un aggregato. – chris

+0

Mi aspetto anche che funzioni. A proposito di un'altra soluzione è quella di omettere le parentesi interne, anche se produce avvertimenti su gcc 4.8. – juanchopanza

+0

Il caso multidimensionale non è diverso dal caso monodimensionale, sebbene il supporto del compilatore possa variare. 'std :: array a {1,2};' è mal formato (gcc 4.7.2 accetterà in modo errato tale codice; clang 3.1 non lo farà). Vedi il duplicato a cui ho collegato sopra. La risposta breve è: questo è un difetto noto nello standard di linguaggio C++ 11. –

risposta

30

std::array<T, N> è un aggregato che contiene una matrice C. Per inizializzare, è necessario bretelle esterne per la classe stessa e bretelle interne per la matrice C:

std::array<int, 3> a1 = { { 1, 2, 3 } }; 

Applicando questa logica per una matrice 2D dà questo:

std::array<std::array<int, 3>, 2> a2 { { { {1, 2, 3} }, { { 4, 5, 6} } } }; 
//         ^^^^   ^^ 
//         | | | |   | | 
//         | +-|-+------------|-+ 
//         +-|-+-|------------+---- C++ class braces 
//          | | 
//          +---+--- member C array braces 
+2

Ma questo funziona bene: 'std :: array a1 {1, 2, 3};'? – PiotrNycz

+2

@PiotrNycz: solo se sei molto sciatto e ignori tutti gli avvisi. Il mio compilatore dice, 'avviso: parentesi mancanti attorno all'inizializzatore per 'std :: array :: value_type [3] {aka int [3]}' [-Wissing-braces]'. –

+0

Ho capito ora, grazie. Ho aggiunto al mio esempio di domanda con C. – PiotrNycz

Problemi correlati