2014-09-03 4 views
7

Mi chiedo se un initializer_list<T> richiede che T abbia un operatore di assegnazione. Il seguenteinitializer_list <T> requisito operatore di assegnazione su T

struct Foo 
{ 
    Foo& operator=(const Foo&) = delete; 
}; 

std::vector<Foo> f = { Foo(), Foo() }; 

compila il clangore 3.4.2 ma fallisce su Visual Studo 2013 con una "error C2280: 'Foo &Foo::operator =(const Foo &)' : attempting to reference a deleted function". Presumo che il clang sia corretto qui, ma volevo verificare che non ci sia bisogno che T sia assegnabile.

risposta

6

std::initializer_list<T> non richiede T per essere assegnabile in alcun modo, perché la copia di oggetti std::initializer_list è superficiale - non copia i dati sottostanti.

Si riceve l'errore perché MSVC 2013 (e sotto) non supporta la generazione automatica di costruttori di mosse e gli operatori di spostamento di spostamento. Quindi l'errore deriva effettivamente da std::vector che tenta di copiare dall'elenco di inizializzazione, non dall'elenco di inizializzatore stesso.

E 'ancora una domanda per cui si attiva l'errore, dal momento che il costruttore std::vector prendendo std::initializer_list richiede solo il tipo di essere EmplaceConstructible e possibilmente MoveInsertable, nessuno dei quali utilizza le assegnazioni.

+0

Molto interessante, quando si dice "generazione automatica del costruttore di spostamenti" intendi nello std :: initializer_list stesso o nel tipo T. Ho provato Fooas segue struct Foo { Foo() {} Foo (const Foo e) {} Foo (Foo &&) {} Foo & operator = (const Foo &) = cancella; Foo & operator = (Foo &&) = elimina; }; – goneskiing

+0

@goneskiing Intendevo nel tipo 'Foo' (in qualsiasi tipo di classe definita dall'utente, davvero). Naturalmente, si applica anche a 'std :: initializer_list', ma lì, come autori di librerie, possono aggirarlo definendo esplicitamente le operazioni di spostamento. Non che ne abbiano bisogno; come ho detto, 'std :: initializer_list' è un involucro poco profondo (probabilmente solo due puntatori interni). – Angew

+0

Così, quando aggiungo esplicitamente un costruttore di mosse a Foo, ottengo ancora un errore, presumo che ciò significhi che l'inizializzatore di VS 2013 è incasinato. Ho provato VS 14 CTP 3 e che funziona con l'originale Foo – goneskiing