2015-09-21 8 views
8

Ricordo qualcuno una volta mi diceva,È auto una parola chiave facoltativa in loop basati su cicli?

"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."

Che è una vera dichiarazione?
La seguente sintassi C++ è valida per il codice?

for (elem : range){...} 

Avevo pensato che questo era già sintassi valida, ma quando sono andato a compilare con
clang++ --std=c++1z, mi è stato mostrato il seguente errore:

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

Il compilatore riconosce ancora questo come un range basato su loop, quindi perché non può anche derivare il tipo?

+0

Questo è stato discusso per l'introduzione in C++ 17. Affinché questa proposta abbia un senso, è necessario sostenere che la sintassi rimane inequivocabile, che è ciò che fa la citazione. Non sono sicuro di come sia lo stato attuale delle cose. – 5gon12eder

+1

@ 5gon12eder: Penso che sia stato accolto con molta preoccupazione, soprattutto per quanto riguarda il nome shadowing (ad esempio se 'elem' è già un nome in ambito, cosa succede se qualcuno lo aggiunge in seguito, ecc. –

+0

Questa sintassi è stata proposta da Stephan T Lavavej per C++ 17, e sarebbe zucchero sintattico per 'for (auto && elem: range)'. Il clang IIRC lo ha implementato come parte di '-std = C++ 1z', ma quando la proposta è stata rifiutata, probabilmente – Praetorian

risposta

2

Questa è davvero una domanda per ELL ...

La frase è scritta nel caso congiuntivo, il che significa che si sta parlando di una situazione puramente ipotetica, non le regole linguistiche effettive. Congiuntivo viene utilizzato per situazioni controfattuali.

+1

Chiedo informazioni sulle regole della lingua. Se non fa parte della lingua , quindi suppongo che la risposta sia solo "no". Ma con l'in-flush delle proposte e la crescita spessa di C++, non sono sicuro di dove posso verificare se questo è già definito nella lingua, e se il mio compilatore deve solo recuperare. –

+0

@TrevorHickey: C++ 1z è ancora in corso di modifica. Stai chiedendo dell'ultima bozza (su https://isocpp.org/std/the-standard, in alto a sinistra)? –

+0

Sì, l'ultima bozza. Una conferma che questo sarà effettivamente supportato in futuro. –

4

La sintassi richiede un tipo per un'istruzione range-for, anche se è auto. for (elem : range) {...} è un errore di sintassi, quindi tecnicamente sì, è vero, la lingua potrebbe indicare che questo è equivalente a for (auto elem : range) {...}.

Ci sono almeno due problemi principali con questo, però:

La prima è che for (T elem : range) non richiede T utilizzare auto. Se il compilatore vede for (elem, non avrebbe ancora modo di sapere se elem è un po 'typedef da un ambito esterno o una variabile appena dichiarata. Non è ambiguo, ma è un po 'complicato per i compilatori gestire correttamente.

Il secondo è che si ottiene la domanda su quale dovrebbe essere l'impostazione predefinita. Argomenti legittimi possono essere fatti per auto. Argomenti legittimi possono essere fatti per auto &. Argomenti legittimi possono essere fatti per const auto &. L'approccio attuale lascia solo al programmatore la scelta. Argomenti legittimi potrebbero probabilmente essere (non sono del tutto sicuro) anche per alcuni di quelli con auto sostituito da decltype(auto).

+0

È un buon punto che "auto" non sia l'opzione migliore in molti casi (forse anche la maggior parte), e quindi non dovrebbe essere un default implicito. –

9

L': sintassi

for (elem : range){...} 

al momento non è valido, ma non c'era una proposta per rendere questa sintassi valido e la sintassi è supportata in gcc 5.2 (see it live):

#include <vector> 

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

    for(elem : v) 
    { 
    } 
} 

e se proviamo questo in modalità C++ 14:

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

Quindi questo funzionerebbe chiaramente ed è stato implementato in gcc. Sembra che questa funzione sia stata rimossa in gcc 6.0.

Per quanto posso dire questo è stato implementato in gcc con l'aspettativa che proposal N3853: Range-Based For-Loops: The Next Generation sarebbe accettato, ma è stata respinta e la versione aggiornata N3994 dice:

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.

Possiamo vedere che è stata respinta dalla EWG issue 81 e possiamo anche vederlo dallo Urbana meeting minutes. Sebbene ci siano molti problemi con la proposta, ritengo che STL abbia formulato una serie convincente di argomentazioni nella sezione Domande e risposte della proposta e sono rimasto deluso dal fatto che la proposta sia stata respinta.

+0

Per curiosità, sei rimasto deluso dal fatto che i parametri lambda tipografici venivano rifiutati? '[] (x, y) {}' per esempio. – chris

+0

@chris bene i problemi sollevati in [Appendice B di N3559] (http://open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3559.pdf) sembrano più facili da accettare come veri problemi per me ma forse mi mancano alcuni dettagli delle obiezioni a N3994. –

+0

Vero, e ho dimenticato i concetti in lambda contro loro essendo meno utili in cicli basati su intervalli. Mi è piaciuta particolarmente anche l'omissione del loop. – chris

Problemi correlati