2012-02-05 19 views
7

Anche se mi piacciono molto le nuove funzionalità in C++ 11, a volte mi sento come se mi mancassero alcune delle sue sottigliezze.std :: inizializzazione elenco inizializzatore array nell'elenco di inizializzazione

L'inizializzazione dell'array int funziona correttamente, l'inizializzazione del vettore Element2 funziona correttamente, ma l'inizializzazione dell'array Element2 non riesce. Penso che la sintassi corretta dovrebbe essere la linea non commentata, ma nessuno dei tentativi di inizializzazione è riuscito per me.

#include <array> 
#include <vector> 

class Element2 
{ 
    public: 
      Element2(unsigned int Input) {} 
      Element2(Element2 const &Other) {} 
}; 

class Test 
{ 
    public: 
      Test(void) : 
        Array{{4, 5, 6}}, 
        Array2{4, 5}, 
        //Array3{4, 5, 6} 
        Array3{{4, 5, 6}} 
        //Array3{{4}, {5}, {6}} 
        //Array3{{{4}, {5}, {6}}} 
        //Array3{Element2{4}, Element2{5}, Element2{6}} 
        //Array3{{Element2{4}, Element2{5}, Element2{6}}} 
        //Array3{{{Element2{4}}, {Element2{5}}, {Element2{6}}}} 
        {} 
    private: 
      std::array<int, 3> Array; 
      std::vector<Element2> Array2; 
      std::array<Element2, 3> Array3; 
}; 

int main(int argc, char **argv) 
{ 
    Test(); 
    return 0; 
} 

Ho provato questo su g ++ 4.6.1 e 4.6.2 in MinGW.

Come devo procedere correttamente per l'inizializzazione di questo array? È possibile?

+0

Immagino che questo non abbia molto a che fare con gli elenchi di inizializzazione. Sarebbe opportuno modificare la domanda per renderla più precisa? – rendaw

risposta

6

Il modo corretto di procedere è Array{{4, 5, 6}}. Non è possibile omettere le parentesi durante l'inizializzazione di un membro con inizializzazione aggregata. L'unica volta che è possibile omettere le parentesi graffe è in una dichiarazione della forma

T t = { ... } 

Quindi nel tuo caso si deve digitare tutte le parentesi: Uno per il std::array sé, e uno per l'array int. Per Array3, anche la sintassi è corretta, poiché int può essere convertito implicitamente in Element2.

Da quelli restanti commentati, lo Array3{{{4}, {5}, {6}}}, e Array3{{{Element2{4}}, {Element2{5}}, {Element2{6}}}} funzionano anche, ma sono più verbosi. Comunque, dal punto di vista concettuale, lo Array3{{{4}, {5}, {6}}} produce la minor quantità di provvisori su implementazioni che non eseguono la copia elisione (immagino che sia irrilevante, ma comunque buono da sapere), anche meno dello Array3{{4, 5, 6}}, perché invece di inizializzare la copia si usa l'inizializzazione della lista di copia per il tuo Element2, che non produce un intermediario temporaneo di progettazione.

+0

Stai dicendo che dovrebbe funzionare correttamente e GCC è rotto? Perché l'OP sta dicendo che * tutte * di queste variazioni falliscono. Inoltre, come funziona davvero, dal momento che 'std :: array ' non è un aggregato? Posso citare le specifiche per i requisiti sugli aggregati, e 'std :: array ' non riesce quel test. Puoi citare le specifiche su come un non aggregato può essere inizializzato tramite l'inizializzazione degli aggregati? Non sto dicendo che ti sbagli. Ammetto che non ho mai letto completamente le specifiche del C++ 11. Allo stesso tempo, vorrei alcune prove per la veridicità del vostro reclamo. –

+1

@NicolBolas A quanto ho capito, 'std :: array ' è un aggregato: è una struttura senza un costruttore definito dall'utente ed è esplicitamente citato come aggregato nella descrizione di ''. – hvd

+0

@nico cosa dice hvd –

Problemi correlati