2013-06-29 16 views
8

Nel seguente:ritorno e dedurre automatico std :: initializer_list

auto x = {0}; // auto deduction of std::initializer_list<int> 
auto y = []() -> std::initializer_list<int> { return {0}; }(); //explicit 
auto z = []() { return {0}; }(); // won't compile 

perché non è possibile restituire e auto dedurre il tipo di std :: initializer_list?

+0

Hai provato 'auto z = []() -> Sistema {return {0}; }(); '? –

+1

Nota che ** non ** vuoi che deduca comunque 'initializer_list', perché i valori nella lista hanno una durata del lambda - non sono estesi da un ritorno di funzione. Vengono distrutti prima di poter usare 'y' o' z'. [Ulteriori informazioni] (http://stackoverflow.com/questions/15286450/lifetime-of-a-stdinitializer-list-return-value). La linea 'y' causa UB. –

risposta

7

Bene, perché lo standard dice così, e perché un rinforzato-init-list non è un'espressione. Per il paragrafo 5.1.2/4 del C++ 11 standard:

[...] Se un lambda-espressione non include una trailing-ritorno-tipo, è come se la posteriore-ritorno-tipo denota il tipo seguente:

- se il composto -affermazione è della forma

{attributo-specificatore-seq (opt)returnespressione; }

il tipo dell'espressione restituito dopo Ivalue-to-rvalue conversione (4.1), da matrice a pointer conversione (4.2), e conversione da funzione a puntatore (4.3);

- altrimenti, void.

È possibile che questo rende chiaro che il tipo di ritorno sarà dedotto di essere qualcos'altro poi void se e solo se la dichiarazione return è seguito da un espressione, e un rinforzato-init-list non è di per sé un'espressione - non ha un tipo e non produce un valore. È solo un costrutto linguistico che può essere utilizzato nel contesto dell'inizializzazione.

Quanto sopra fornisce anche un esempio:

[Esempio:

auto x1 = [](int i){ return i; }; // OK: return type is int 
auto x2 = []{ return { 1, 2 }; }; // error: the return type is void (a 
            // braced-init-list is not an expression) 

- esempio fine]

Infine, se la domanda è:

"Perché è stata introdotta una norma speciale per dedurre il tipo di un auto variabili inizializzata da a-init-list rinforzato, mentre una regola simile era non introdotto per dedurre il tipo di ritorno di un lambda quando return è seguito da un rinforzato-init-list? "

Quindi la domanda non è costruttiva.Si noti inoltre, che tipo di deduzione per i modelli non funziona con imbracciò-init-list sia:

template<typename T> 
void foo(T); 

foo({1, 2}); // ERROR! T is NOT deduced to be std::initializer_list<int> 
+0

Grazie Andy per la risposta. Ho pensato che la deduzione per l'auto e i modelli seguissero le stesse regole, ma stai dando un controesempio. –

+0

@ a.lasram: lo fanno nella maggior parte delle situazioni, ma ci sono delle eccezioni. In realtà, penso che quello che ho indicato alla fine della risposta sia l'unica * eccezione *, anche se non ne sono sicuro al 100%. –

+0

@ Andy Prowl - mi dispiace, stessa situazione di auto: foo ({1, 2}) fallisce ma foo > ({1, 2}) passerebbe. –

Problemi correlati