更新:正如核心主席在底引号中所承诺的那样,代码现在格式不正确:
如果一个标识符在一个简单的捕捉显示为说明符-ID的的参数的λ-说明符的参数声明子句,是形成不良的节目。
不久前,有一些关于在lambda中查找名称的问题。他们由N2927解决:
新的措辞不再依赖于查找来重新映射捕获的实体的使用。它更清楚地否认以下解释:lambda的复合语句是在两次通过中处理的,或者该复合语句中的任何名称都可以解析为闭包类型的成员。
查找总是在lambda-expression的上下文中完成的,永远不要在转换为闭包类型的成员函数体之后的“之后”。参见[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
未在捕获中(重新)声明;它在包含lambda表达式的块中声明。参数foo
在嵌套在该外部块中的块中声明(请参阅[basic.scope.block] / 2,其中也明确提到了lambda参数)。查找的顺序显然是从内部到外部块。因此,应该选择参数,即Clang是正确的。
如果您要使捕获成为init-capture,即foo = ""
代替foo
,答案将不清楚。这是因为捕获实际上会引起一个声明,该声明的“ block”没有给出。我就此向核心主席发了信息,他回答
这是问题2211(一个新的问题列表将很快出现在open-std.org网站上,不幸的是,仅占位符解决了许多问题,其中一个是问题;我正在努力填补科纳之前的空白在月底开会)。CWG在我们一月份的电话会议上讨论了此问题,如果捕获名称也是参数名称,则方向是使程序格式错误。