2013-06-29 14 views
8

W poniższym:powrót i auto wywieść 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 

dlaczego nie jest możliwe, aby powrócić i auto wywnioskować typ std :: initializer_list?

+0

Próbowałaś 'auto z = []() -> auto {return {0}; }(); '? –

+1

Zauważ, że ** nie ** chcesz, aby i tak wyprowadzał 'initializer_list', ponieważ wartości na liście mają czas życia lambda - nie są przedłużane przez funkcję return. Są niszczone, zanim użyjesz 'y' lub' z'. [Więcej informacji] (http://stackoverflow.com/questions/15286450/lifetime-of-a-ddinitializer-list-return-value). Linia 'y' powoduje UB. –

Odpowiedz

7

Cóż, ponieważ Standard tak mówi, a także dlatego, żeusztywniona lista inicjująca nie jest wyrażeniem. Zgodnie z pkt 5.1.2/4 C++ 11 Standard:

[...] Jeśli lambda wyrażenie nie obejmuje tylną zwrotny typu, to tak jakby wzdłużny zwrotny typu oznacza typu:

- jeśli związek instrukcja_select ma postać

{atrybut specyfikator-nast (opcjonalnie)returnekspresji; }

typu zwróconej ekspresji po lwartość do RValue konwersji (4,1) Tablica do wskaźnika konwersji (4,2), a konwersja funkcji do wskaźnika (4.3);

- w przeciwnym razie, void.

Powyższe wyjaśnia, że ​​zwracany typ będzie wywnioskować, że nic innego następnie void wtedy i tylko wtedy, gdy oświadczenie return następuje przez ekspresji oraz usztywnione-init-listy nie jest samo w sobie wyrażenie - nie ma typu i nie daje wartości. Jest to tylko konstrukcja językowa, która może być użyta w kontekście inicjalizacji.

Powyższy ust stanowi również przykład:

[Przykład:

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) 

- przykład koniec]

Na koniec, jeśli chodzi o to:

"Dlaczego specjalny przepis został wprowadzony do wydedukowania type auto zmiennej inicjowane z usztywnione-init-listy, podczas gdy podobna zasada była nie wprowadzona do wyciągania typ zwracanej lambda gdy return następuje wzmocniona lista początkowa? "

To pytanie nie jest konstruktywne.Również zauważyć, że typ odliczenie szablonów nie działa z usztywnione inicjalizacji listach albo:

template<typename T> 
void foo(T); 

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

Dzięki Andy za odpowiedź. Myślałem, że odliczanie za auto i szablony są zgodne z tymi samymi regułami, ale podajesz kontrprzykład. –

+0

@ a.lasram: Robią to w większości sytuacji, ale są wyjątki. Właściwie myślę, że ten, który wskazałem na końcu odpowiedzi, jest jedynym wyjątkiem *, chociaż nie jestem w 100% pewny. –

+0

@ Andy Prowl - przepraszam, ta sama sytuacja, co auto: foo ({1, 2}) nie działa, ale foo > ({1, 2}) by przeszło. –

Powiązane problemy