Обновление: как и обещал председатель ядра в нижней цитате, код теперь неправильно сформирован :
Если идентификатор в простом-захвате появляется как описатель-идентификатор параметра в лямбда-описателе «s параметра декларирование-п , программа плохо сформирована.
Некоторое время назад было несколько проблем с поиском имени в лямбдах. Их разрешил N2927 :
Новая формулировка больше не полагается на поиск для переназначения использования захваченных объектов. Он более четко отрицает интерпретацию того, что составной оператор лямбды обрабатывается за два прохода или что любые имена в этом составном операторе могут разрешаться в член типа замыкания.
Поиск всегда выполняется в контексте лямбда-выражения , а не «после» преобразования в тело функции-члена закрывающего типа. См. [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*
};
}
};
- конечный пример ]
(Пример также проясняет, что поиск каким-то образом не учитывает сгенерированный член захвата типа закрытия.)
Имя foo
не (повторно) объявлено в захвате; он объявлен в блоке, включающем лямбда-выражение. Параметр foo
объявлен в блоке, который вложен в этот внешний блок (см. [Basic.scope.block] / 2 , в котором также явно упоминаются лямбда-параметры). Порядок поиска явно от внутренних блоков к внешним . Значит параметр должен быть выбран, то есть Clang прав.
Если бы вы сделали захват init-capture, т.е. foo = ""
вместо этого foo
, ответ был бы неясным. Это потому, что захват теперь фактически вызывает объявление, чей «блок» не задан. Я написал об этом основному стулу, и он ответил
Это проблема 2211 (в ближайшее время на сайте open-std.org появится новый список проблем, к сожалению, с заполнителями только для ряда проблем, из которых это одна из них; я прилагаю все усилия, чтобы заполнить эти пробелы до того, как Kona встреча в конце месяца). CWG обсудила это во время нашей январской телеконференции, и нам нужно сделать программу некорректной, если имя захвата также является именем параметра.