【发布时间】:2016-08-03 18:07:01
【问题描述】:
我不太明白 C++14 标准草案 N4140 5.1.2.12 [expr.prim.lambda] 中的一个例子。
具有关联捕获默认值的 lambda 表达式未显式捕获此变量或具有自动存储持续时间的变量(这不包括已发现引用 initcapture 关联的非静态数据成员的任何 id 表达式),据说如果复合语句隐式捕获实体(即 this 或变量):
- odr-使用实体,或
- 在可能求值的表达式中命名实体,其中封闭的完整表达式取决于在 lambda 表达式的到达范围内声明的通用 lambda 参数。
[示例:
void f(int, const int (&)[2] = {}) { } // #1 void f(const int&, const int (&)[1]) { } // #2 void test() { const int x = 17; auto g = [](auto a) { f(x); // OK: calls #1, does not capture x }; auto g2 = [=](auto a) { int selector[sizeof(a) == 1 ? 1 : 2]{}; f(x, selector); // OK: is a dependent expression, so captures x }; }——结束示例]
所有此类隐式捕获的实体都应在 lambda 表达式的范围内声明。
[ 注意:嵌套的 lambda 表达式对实体的隐式捕获可能会导致其被包含的 lambda 表达式隐式捕获(见下文)。对 this 的隐式 odr 使用可能会导致隐式捕获。 ——尾注]
我认为短语a lambda-expression with an associated capture-default 的开头应该禁止任何隐式捕获(并且已通过注释确认),因此#1 调用将导致错误(关于使用未捕获变量的一些事情)。那么它是如何工作的呢? f 的第一个参数是什么?如果在退出test() 范围后会调用g 怎么办?如果我把#1签名改成void(const int&)呢?
--
upd:感谢大家解释它是如何工作的。稍后我将尝试查找并发布有关此案例的标准参考。
【问题讨论】:
-
x是一个常量表达式。由于引用,ODR 仅用于#2。 -
换句话说,
g的行为就好像它的主体是{ f(17); }。
标签: c++ lambda standards c++14