问题描述
我不太理解C ++ 14标准草案 N4140 5.1.2.12 [expr.prim.lambda]
中的示例。
I can not quite understand an example from C++14 standard draft 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表达式的作用域内声明。
All such implicitly captured entities shall be declared within the reaching scope of the lambda expression.
[注意:嵌套的lambda-expression隐式捕获实体可能会通过包含的lambda-expression导致其隐式捕获(请参见下文)。隐式使用odr会导致隐式捕获。 —尾注]
[ Note: The implicit capture of an entity by a nested lambda-expression can cause its implicit capture by the containing lambda-expression (see below). Implicit odr-uses of this can result in implicit capture. —end note ]
我认为短语带有相关捕获的lambda表达式的开头- default
应该禁止任何隐式捕获(并通过评论确认),因此#1
调用将导致错误(有关使用未捕获的变量的某些信息) )。那么它是如何工作的呢? f
的第一个参数是什么?如果退出 test()
范围后将调用 g
怎么办?如果我将#1
签名更改为 void(const int&)
怎么办?
I thought that the beginning of a phrase a lambda-expression with an associated capture-default
should prohibit any implicit capture (and it's confirmed by comment), therefore #1
call will lead to an error (something about using not captured variable). So how it works? What will be first argument of f
? What if g
will be called after exiting test()
scope? What if I change #1
signature to void(const int&)
?
-
upd:感谢大家对它的工作原理的解释。稍后,我将尝试查找并发布有关此案例的标准参考。
upd: Thanks to all for explanation of how it works. Later I'll try to find and post references to standard about this case.
推荐答案
作为T.C。在他的评论中说,#1不需要捕获,因为 x
在编译时是已知的,因此被烘焙到lambda中。与在编译时如何知道函数 f
一样,因此不需要捕获它。
As T.C. said in his comment, #1 does not require a capture as x
is known at compile time and is therefore baked into the lambda. Not unlike how the function f
is known at compile time so it doesn't need to be captured.
I相信如果将 f
的签名更改为 int const&
,您现在正在尝试传递常量的地址
。因此,它可能会发生变化,因此需要按值或引用捕获 x
。
I believe if you change f
's signature to int const &
you are now attempting to pass the address of the constant which is on the stack, thus subject to changes, and it would require capturing x
by value or reference.
这篇关于在lambda中使用未捕获的变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!