Update: Wie vom Core Chair im unteren Zitat versprochen, ist der Code jetzt schlecht geformt :
Wenn eine Kennung in einer einfachen Erfassungs erscheint als declarator-ID eines Parameters des Lambda-declarator ‚s - Parameter-Deklaration-Klausel wird das Programm schlecht ausgebildet.
Vor einiger Zeit gab es einige Probleme bei der Namenssuche in Lambdas. Sie wurden von N2927 gelöst :
Der neue Wortlaut basiert nicht mehr auf der Suche, um die Verwendung erfasster Entitäten neu zuzuordnen. Es bestreitet deutlicher die Interpretationen, dass die zusammengesetzte Anweisung eines Lambdas in zwei Durchgängen verarbeitet wird oder dass alle Namen in dieser zusammengesetzten Anweisung in ein Mitglied des Schließungstyps aufgelöst werden könnten.
Die Suche erfolgt immer im Kontext des Lambda-Ausdrucks , niemals "nach" der Transformation in den Elementfunktionskörper eines Schließungstyps. Siehe [expr.prim.lambda] / 8 :
Die Lambda-Ausdruck ‚s - Verbindung-Anweisung liefert die Funktion Körper ([dcl.fct.def]) der Funktion Call - Betreiber, aber für die Zwecke der Namenssuche, [...], die Verbindung-Anweisung wird im Kontext betrachtet von der Lambda-Ausdruck . [ Beispiel :
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*
};
}
};
- Beispiel beenden ]
(Das Beispiel macht auch deutlich, dass bei der Suche das generierte Erfassungselement des Schließungstyps nicht berücksichtigt wird.)
Der Name foo
wird in der Aufnahme nicht (neu) deklariert. Es wird in dem Block deklariert, der den Lambda-Ausdruck enthält. Der Parameter foo
wird in einem Block deklariert, der in diesem äußeren Block verschachtelt ist (siehe [basic.scope.block] / 2 , in dem auch Lambda-Parameter explizit erwähnt werden). Die Reihenfolge der Suche ist eindeutig von inneren zu äußeren Blöcken . Daher sollte der Parameter ausgewählt werden, dh Clang ist richtig.
Wenn Sie die Erfassung zu einer Init-Erfassung machen würden, dh foo = ""
stattdessen foo
, wäre die Antwort nicht klar. Dies liegt daran, dass die Erfassung jetzt tatsächlich eine Deklaration induziert, deren "Block" nicht angegeben ist. Ich habe den Hauptstuhl darüber informiert, der geantwortet hat
Dies ist Ausgabe 2211 (eine neue Problemliste wird in Kürze auf der Website open-std.org erscheinen, leider nur mit Platzhaltern für eine Reihe von Ausgaben, von denen dies eine ist. Ich arbeite hart daran, diese Lücken vor der Kona zu schließen Treffen am Ende des Monats). CWG hat dies während unserer Telefonkonferenz im Januar besprochen. Die Richtung besteht darin, das Programm schlecht zu gestalten, wenn ein Erfassungsname auch ein Parametername ist.