在lambda中使用未捕获的变量
Using of not captured variable in lambda
我不太理解C++14标准草案N4140 5.1.2.12 [expr.prim.lambda]
中的一个例子。
如果复合语句
- 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表达式(见下文)对其进行隐式捕获。对此的隐式odr使用可能会导致隐式捕获
我认为短语a lambda-expression with an associated capture-default
的开头应该禁止任何隐式捕获(并通过注释进行了确认),因此#1
调用将导致错误(关于使用未捕获的变量)。那么它是如何工作的呢?f
的第一个论点是什么?如果在退出test()
作用域后将调用g
,该怎么办?如果我将#1
签名更改为void(const int&)
,该怎么办?
--
upd:感谢大家对它工作原理的解释。稍后,我将尝试查找并发布有关此案例的标准参考资料。
正如T.C.在评论中所说,#1不需要捕获,因为x
在编译时是已知的,因此被烘焙到lambda中。这与函数f
在编译时的已知方式并无不同,因此不需要捕获它。
我相信,如果您将f
的签名更改为int const &
,您现在正试图传递堆栈上常量的地址,因此可能会发生更改,并且需要通过值或引用捕获x
。
相关文章:
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 在 lambda 捕获中声明的变量的类型推导
- 我可以在这里替换什么,因为我不能在 C# 中使用隐式变量的 lambda 函数?
- 在 C++ 中访问 lambda 捕获初始化变量
- Visual C++: MSVC vs. GCC+CLANG: 处理 lambda 捕获类成员变量,正确的方法是什么?
- 作为模板变量的 Lambda
- 变量不在 lambda 的范围内
- 为什么 lambda 采用变量的初始值
- 为什么捕获 lambda 不捕获变量?
- C++ lambda:如何'freeze'局部变量的值?
- 获取具有静态局部变量的绑定/推断捕获 lambda 的函数指针
- Simulink "Access Violation"写入 C++ lambda 函数捕获列表中的 PWork 变量
- C++使用 lambda 初始化变量
- 如何在 lambda 表达式中传递变量?
- C++将 lambda 函数另存为成员变量,而不使用函数指针进行优化
- C++ lambda - 捕获静态成员变量
- 当使用lambda进行变量的复杂初始化时,如何处理从内部抛出的lambda外部异常
- 无法通过引用捕获 lambda 中的成员变量
- 是否允许在作为静态数据结构成员的lambda函数中捕获变量
- C 递归变量lambda