Aktualizacja: zgodnie z obietnicą krzesła Core w dolnym cytacie, kod to teraz źle sformułowany :
Jeżeli identyfikator w prosty wychwytywania występuje jako declarator-id parametru z lambda-declarator „S -parametrów zgłoszenia klauzula program jest słabo formowane.
Jakiś czas temu było kilka problemów dotyczących wyszukiwania nazw w lambdach. Zostały rozwiązane przez N2927 :
Nowe sformułowanie nie polega już na wyszukiwaniu w celu ponownego odwzorowania użycia przechwyconych jednostek. Bardziej wyraźnie zaprzecza interpretacjom, że instrukcja złożona lambda jest przetwarzana w dwóch przebiegach, lub że jakiekolwiek nazwy w tej instrukcji złożonej mogą być rozpoznawane jako element członkowski typu zamknięcia.
Wyszukiwanie jest zawsze wykonywane w kontekście wyrażenia lambda , nigdy „po” transformacji do treści funkcji składowej typu zamknięcia. Zobacz [expr.prim.lambda] / 8 :
W lambda ekspresji „s Związek instrukcja_select daje funkcyjnego korpus ([]) dcl.fct.def operatora wywołania funkcji, ale dla celów wyszukiwania nazw [...], sygnał związek instrukcja_select rozpatrywane są w kontekście lambda ekspresji . [ Przykład :
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*
};
}
};
- przykład końca ]
(Z przykładu jasno wynika również, że wyszukiwanie w jakiś sposób nie uwzględnia wygenerowanego elementu przechwytywania typu zamknięcia).
Imię foo
nie jest (ponownie) deklarowane podczas brania; jest zadeklarowana w bloku zawierającym wyrażenie lambda. Parametr foo
jest zadeklarowany w bloku, który jest zagnieżdżony w tym zewnętrznym bloku (zobacz [basic.scope.block] / 2 , który również wyraźnie wspomina o parametrach lambda). Kolejność wyszukiwania jest wyraźnie od bloków wewnętrznych do zewnętrznych . Stąd parametr powinien być wybrany, czyli Clang ma rację.
Gdybyś miał zrobić przechwycenie jako przechwytywanie początkowe, tj. foo = ""
Zamiast foo
, odpowiedź nie byłaby jasna. Dzieje się tak, ponieważ przechwytywanie w rzeczywistości wywołuje teraz deklarację, której „blokada” nie została podana. Wysłałem wiadomość do głównego krzesła, który odpowiedział
To jest numer 2211 (nowa lista problemów pojawi się wkrótce na stronie open-std.org, niestety tylko z symbolami zastępczymi dla wielu problemów, z których jest jeden; ciężko pracuję, aby wypełnić te luki przed Kona spotkanie pod koniec miesiąca). CWG omawiało to podczas naszej styczniowej telekonferencji, a kierunek jest taki, aby program był źle sformułowany, jeśli nazwa przechwytywania jest również nazwą parametru.