Ответ 1
Обновление: как обещал стул Core в нижней цитате, код теперь плохо сформирован:
Если идентификатор в простом захвате появляется как идентификатор объявления параметра lambda-declarator parameter-declaration-clause, программа плохо сформирована.
Было несколько вопросов, касающихся поиска имени в lambdas некоторое время назад. Они были разрешены N2927:
Новая формулировка больше не зависит от поиска для повторного использования использования захваченных объектов. Это более четко отклоняет интерпретации, которые обрабатывает оператор lambda-состав в течение двух проходов или что любые имена в этом составном заявлении могут быть разрешены для члена типа закрытия.
Поиск выполняется всегда в контексте лямбда-выражения, никогда не "после" преобразования в тело функции члена типа закрытия. См. [expr.prim.lambda]/8:
Компонент-оператор лямбда-выражения дает функцию-тело ([dcl.fct.def]) оператора вызова функции, но для целей поиска имени [...] составной оператор рассматривается в контексте лямбда-выражения. [Пример:
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* }; } };
-end пример]
(В этом примере также ясно, что поиск не позволяет каким-либо образом рассмотреть созданный элемент захвата типа замыкания.)
Имя foo
не объявлено в записях; он объявляется в блоке, охватывающем лямбда-выражение. Параметр foo
объявляется в блоке, который вложен в этот внешний блок (см. [basic.scope.block]/2, который также явно упоминает лямбда-параметры). Порядок поиска явно от внутреннего к внешним блокам. Следовательно, параметр должен быть выбран, то есть, Кланг прав.
Если вы хотите сделать захват init-capture, т.е. foo = ""
вместо foo
, ответ будет неясным. Это связано с тем, что теперь захват фактически вызывает объявление, чей "блок" не указан. Я послал основной стул на это, который ответил
Это проблема 2211 (скоро появится список новых проблем на сайте open-std.org, к сожалению, с просто заполнителями для ряда вопросов, из которых это одно: я изо всех сил стараюсь заполнить эти пробелы до встречи Коны в конце месяца). CWG обсудила это во время январской телеконференции, а направлено на то, чтобы программа была плохо сформирована, если имя захвата также является именем параметра.