Atualização: conforme prometido pela cadeira Core na citação inferior, o código agora está mal formado :
Se um identificador em um simples de captura aparece como o declarator-id de um parâmetro do lambda-declarator 's parâmetro de declaração cláusula , o programa está mal-formado.
Houve alguns problemas relacionados à pesquisa de nomes em lambdas há um tempo atrás. Eles foram resolvidos pelo N2927 :
A nova redação não depende mais da pesquisa para remapear os usos das entidades capturadas. Nega mais claramente as interpretações de que a instrução composta de um lambda é processada em duas passagens ou que qualquer nome nessa instrução composta possa ser resolvido para um membro do tipo de fechamento.
A pesquisa é sempre feita no contexto da expressão lambda , nunca "depois" da transformação no corpo da função de membro de um tipo de fechamento. Veja [expr.prim.lambda] / 8 :
O lambda-expressão do composto-declaração produz a função de corpo ([dcl.fct.def]) do operador da chamada de função, mas para fins de pesquisa de nome, [...], o composto-declaração é considerado no contexto de a expressão lambda . [ Exemplo :
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*
};
}
};
- exemplo final ]
(O exemplo também deixa claro que a pesquisa não considera de alguma forma o membro de captura gerado do tipo de fechamento.)
O nome foo
não é (re) declarado na captura; é declarado no bloco que encerra a expressão lambda. O parâmetro foo
é declarado em um bloco aninhado nesse bloco externo (consulte [basic.scope.block] / 2 , que também menciona explicitamente parâmetros lambda). A ordem da pesquisa é claramente do interior para o exterior . Portanto, o parâmetro deve ser selecionado, ou seja, Clang está certo.
Se você fizesse da captura uma captura init, ou seja, em foo = ""
vez de foo
, a resposta não seria clara. Isso ocorre porque a captura agora na verdade induz uma declaração cujo "bloco" não é fornecido. Enviei uma mensagem para a cadeira principal, que respondeu
Esta é a edição 2211 (uma nova lista de questões aparecerá em breve no site open-std.org, infelizmente com apenas espaços reservados para vários problemas, dos quais este é um; estou trabalhando duro para preencher essas lacunas antes do Kona reunião no final do mês). O CWG discutiu isso durante nossa teleconferência de janeiro, e a direção é tornar o programa mal formado se um nome de captura também for um nome de parâmetro.