在 lambda 中使用未捕获的变量
Using of not captured variable in lambda
我不太理解 C++14 标准草案中的一个例子 N4140 5.1.2.12 [expr.prim.lambda]
。
A lambda-expression with an associated capture-default that does not explicitly capture this or a variable with automatic storage duration (this excludes any id-expression that has been found to refer to an initcapture’s associated non-static data member), is said to implicitly capture the entity (i.e., this or a variable) if the compound-statement:
- odr-uses the entity, or
- names the entity in a potentially-evaluated expression where the enclosing full-expression depends on a generic lambda parameter declared within the reaching scope of the lambda-expression.
[ Example:
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
};
}
—end example ]
All such implicitly captured entities shall be declared within the reaching scope of the lambda expression.
[ 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 ]
我认为短语 a lambda-expression with an associated capture-default
的开头应该禁止任何隐式捕获(并且已通过注释确认),因此 #1
调用将导致错误(有关使用未捕获变量的内容).那么它是如何工作的呢? f
的第一个参数是什么?如果在退出 test()
作用域后调用 g
怎么办?如果我将 #1
签名更改为 void(const int&)
会怎样?
--
upd:感谢大家解释它是如何工作的。稍后我将尝试查找并 post 参考有关此案例的标准。
作为T.C。在他的评论中说,#1 不需要捕获,因为 x
在编译时已知,因此被烘焙到 lambda 中。与函数 f
在编译时已知的方式没有什么不同,因此不需要捕获它。
我相信,如果您将 f
的签名更改为 int const &
,您现在正试图传递堆栈中常量的地址,因此会发生变化,并且需要按值或引用捕获 x
。
我不太理解 C++14 标准草案中的一个例子 N4140 5.1.2.12 [expr.prim.lambda]
。
A lambda-expression with an associated capture-default that does not explicitly capture this or a variable with automatic storage duration (this excludes any id-expression that has been found to refer to an initcapture’s associated non-static data member), is said to implicitly capture the entity (i.e., this or a variable) if the compound-statement:
- odr-uses the entity, or
- names the entity in a potentially-evaluated expression where the enclosing full-expression depends on a generic lambda parameter declared within the reaching scope of the lambda-expression.
[ Example:
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 }; }
—end example ]
All such implicitly captured entities shall be declared within the reaching scope of the lambda expression.
[ 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 ]
我认为短语 a lambda-expression with an associated capture-default
的开头应该禁止任何隐式捕获(并且已通过注释确认),因此 #1
调用将导致错误(有关使用未捕获变量的内容).那么它是如何工作的呢? f
的第一个参数是什么?如果在退出 test()
作用域后调用 g
怎么办?如果我将 #1
签名更改为 void(const int&)
会怎样?
--
upd:感谢大家解释它是如何工作的。稍后我将尝试查找并 post 参考有关此案例的标准。
作为T.C。在他的评论中说,#1 不需要捕获,因为 x
在编译时已知,因此被烘焙到 lambda 中。与函数 f
在编译时已知的方式没有什么不同,因此不需要捕获它。
我相信,如果您将 f
的签名更改为 int const &
,您现在正试图传递堆栈中常量的地址,因此会发生变化,并且需要按值或引用捕获 x
。