Aggiornamento: come promesso dalla cattedra Core nella citazione in basso, il codice è ora mal formato :
Se un identificatore in una semplice cattura appare come il dichiaratore-id di un parametro della lambda-dichiaratore 's parametro-dichiarazione-clausola , il programma è mal-formata.
Qualche tempo fa c'erano alcuni problemi riguardanti la ricerca dei nomi in lambdas. Sono stati risolti da N2927 :
La nuova formulazione non si basa più sulla ricerca per rimappare gli usi delle entità acquisite. Nega più chiaramente le interpretazioni che un'istruzione composta lambda viene elaborata in due passaggi o che i nomi in tale istruzione composta potrebbero risolversi in un membro del tipo di chiusura.
La ricerca viene sempre eseguita nel contesto dell'espressione lambda , mai "dopo" la trasformazione nel corpo della funzione membro di un tipo di chiusura. Vedi [expr.prim.lambda] / 8 :
Il lambda-espressione s' composto-dichiarazione si ottiene la funzione di corpo ([dcl.fct.def]) dell'operatore funzione di chiamata, ma per scopi di ricerca del nome, [...], il composto-dichiarazione è considerata nel contesto di l' espressione lambda . [ Esempio :
struct S1 {
int x, y;
int operator()(int);
void f() {
[=]()->int {
return operator()(this->x+y); // equivalent to: S1::operator()(this->x+(*this).y)
// and this has type S1*
};
}
};
- fine esempio ]
(L'esempio chiarisce inoltre che la ricerca non considera in qualche modo il membro di acquisizione generato del tipo di chiusura.)
Il nome foo
non viene (ri) dichiarato nella cattura; è dichiarato nel blocco che racchiude l'espressione lambda. Il parametro foo
è dichiarato in un blocco nidificato in quel blocco esterno (vedere [basic.scope.block] / 2 , che menziona esplicitamente anche i parametri lambda). L'ordine di ricerca è chiaramente dai blocchi interni a quelli esterni . Quindi il parametro dovrebbe essere selezionato, cioè Clang ha ragione.
Se dovessi rendere la cattura una init-cattura, ovvero foo = ""
invece di foo
, la risposta non sarebbe chiara. Questo perché l'acquisizione ora induce effettivamente una dichiarazione il cui "blocco" non viene dato. Ho mandato un messaggio alla sedia principale su questo, che ha risposto
Questo è il numero 2211 (un nuovo elenco di numeri apparirà sul sito open-std.org a breve, sfortunatamente con solo segnaposto per una serie di problemi, di cui questo è uno; sto lavorando sodo per colmare quelle lacune prima della Kona incontro alla fine del mese). CWG ne ha discusso durante la nostra teleconferenza di gennaio e la direzione è di rendere il programma mal formato se un nome di acquisizione è anche un nome di parametro.