2015-09-21 28 views
8

Pamiętam, ktoś kiedyś powiedział mi,Czy auto jest opcjonalnym słowem kluczowym w zakresie zależnym od pętli?

"there is no need for auto inside range-based for loops. It would not be ambiguous in the language if we were to remove it."

Czy to prawdziwy stwierdzeniem?
Czy następujący kod działa poprawnie w C++?

for (elem : range){...} 

przypuszczałem był już ważny składnia, ale kiedy poszedłem do kompilacji z
clang++ --std=c++1z, pokazano mi następujący błąd:

range-based for loop requires type for loop variable 
for (elem: range){ 

Kompilator nadal rozpoznaje to jako pasmo oparta na pętli, więc dlaczego nie może również wyprowadzić typu?

+0

Zostało to omówione do wprowadzenia w C++ 17. Aby ta propozycja miała sens, trzeba było argumentować, że składnia pozostaje jednoznaczna, co robi cytat. Nie jestem jednak pewien, jaki jest obecny stan rzeczy. – 5gon12eder

+1

@ 5gon12eder: Myślę, że został przyjęty z dużym niepokojem, szczególnie w kwestii cienia nazwy (np. Czy 'elem' jest już nazwą w zakresie, co jeśli ktoś doda ją później, itp. –

+0

Ta składnia została zaproponowana przez Stephan T. Lavavej dla C++ 17 i byłby to cukier syntaktyczny dla 'for (auto && elem: range)'. Clang IIRC zaimplementował to jako część '-std = C++ 1z', ale kiedy propozycja została odrzucona, prawdopodobnie zmienił to na błąd – Praetorian

Odpowiedz

2

Tak naprawdę jest to pytanie dla ELL ...

zdanie jest napisane w trybie łączącym przypadku, co oznacza, że ​​jest mówić o czysto hipotetycznej sytuacji, a nie rzeczywiste zasady językowe. Subjunctive jest używany w sytuacjach kontrfaktycznych.

+1

Pytam o zasady językowe. Jeśli nie jest to część języka , więc przypuszczam, że odpowiedź brzmi "nie". Ale dzięki wbudowanym propozycjom i zwiększonemu wzrostowi C++, nie jestem pewien, czy mogę zweryfikować, czy jest to już zdefiniowane w języku, i czy mój kompilator musi po prostu nadrobić zaległości. –

+0

@ TrevorHickey: C++ 1z jest ciągle edytowany. Czy pytasz o najnowszą wersję roboczą (na https://isocpp.org/std/the-standard, w lewym górnym rogu)? –

+0

Tak, najnowszy projekt. Potwierdzenie, że rzeczywiście będzie to wspierane w przyszłości. –

4

Składnia wymaga typu dla instrukcji range-for, nawet jeśli jest to auto. for (elem : range) {...} jest błędem składni, więc technicznie rzecz biorąc, tak, to prawda, język może stwierdzić, że jest to odpowiednik for (auto elem : range) {...}.

Istnieją co najmniej dwa główne problemy związane z tym, iż:

Pierwszym jest to, że nie wymaga for (T elem : range)T używać auto. Jeśli kompilator zobaczy for (elem, to nie będzie jeszcze wiedzieć, czy elem jest jakieś typedef z zewnętrznego zakresu lub nowo zadeklarowaną zmienną. Nie jest niejednoznaczny, ale kompilatory są nieco skomplikowane w obsłudze.

Po drugie, pojawia się pytanie, co powinno być domyślne. Uzasadnione argumenty mogą być złożone na auto. Uzasadnione argumenty mogą być złożone na auto &. Uzasadnione argumenty mogą być złożone na const auto &. Obecne podejście pozwala tylko wybrać programistę. Uzasadnione argumenty mogą prawdopodobnie (nie jestem do końca pewny) także dla tych z auto zastąpionych przez decltype(auto).

+0

To dobrze, że 'auto' nie jest najlepszą opcją w wielu (może nawet większości) przypadkach, a zatem nie powinno być domyślnym domyślnym. –

9

: składnia

for (elem : range){...} 

obecnie nie jest ważne, ale nie była propozycja, aby ten ważny składni i składnia jest obsługiwana w gcc 5.2 (see it live):

#include <vector> 

int main() 
{ 
    std::vector<int> v ; 

    for(elem : v) 
    { 
    } 
} 

i jeśli spróbujemy tego w trybie C++ 14, będzie to:

warning: range-based for loop without a type-specifier only available with -std=c++1z or -std=gnu++1z

To by wyraźnie działało i zostało zaimplementowane w gcc. Wygląda na to, że ta funkcja została usunięta w gcc 6.0.

O ile mogę powiedzieć ten został wdrożony w gcc z oczekiwaniem, że proposal N3853: Range-Based For-Loops: The Next Generation będą akceptowane, ale została ona odrzucona i zaktualizowana wersja N3994 mówi:

This updates N3853 (see [1]) which proposed the syntax "for (elem : range)", by adding support for attributes and answering additional questions. Please see the original proposal for the rationale behind this feature, which is not repeated here.

Widzimy to zostało odrzucone z EWG issue 81 i możemy to również zobaczyć z Urbana meeting minutes. Chociaż propozycję uważam za dużo, uważam, że STL przedstawiła przekonywującą listę argumentów w części pytania i odpowiedzi wniosku i byłem rozczarowany, że wniosek został odrzucony.

+0

Z ciekawości rozczarowałeś się, że odrzucone parametry lambda bez formy? Na przykład: [] (x, y) {}. – chris

+0

@chris i kwestie poruszone w [Dodatku B N3559] (http://open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3559.pdf) wydają się łatwiejsze do zaakceptowania jako prawdziwe problemy dla mnie ale być może brakuje mi niektórych szczegółów zastrzeżeń do N3994. –

+0

To prawda, i zapomniałem o koncepcjach lambdas, a mniej o tym, że są mniej użyteczne w pętlach opartych na zasięgu. Szczególnie podobało mi się również pominięcie w pętli. – chris