c++11 lambdas 会捕获它们不使用的变量吗?

2021-12-23 00:00:00 lambda c++ c++11

当我使用 [=] 表示我希望通过 lambda 中的值捕获所有局部变量时,是否会导致 all 局部变量在被复制的函数,或者只是被 lambda 使用的所有局部变量?

When I use [=] to indicate that I would like all local variables to be captured by value in a lambda, will that result in all local variables in the function being copied, or just all local variables that are used by the lambda?

例如,如果我有:

vector<int> my_huge_vector(100000);
int my_measly_int;
some_function([=](int i){ return my_measly_int + i; });

是否会复制 my_huge_vector,即使我不在 lambda 中使用它?

Will my_huge_vector be copied, even though I don't use it in the lambda?

推荐答案

捕获列表中明确命名的每个变量都被捕获.默认捕获将仅捕获 (a) 未在捕获列表中明确命名和 (b) 在 lambda 表达式主体中使用的变量.如果变量没有明确命名并且您没有在 lambda 表达式中使用该变量,则不会捕获该变量.在您的示例中,未捕获 my_huge_vector.

Each variable expressly named in the capture list is captured. The default capture will only capture variables that are both (a) not expressly named in the capture list and (b) used in the body of the lambda expression. If a variable is not expressly named and you don't use the variable in the lambda expression, then the variable is not captured. In your example, my_huge_vector is not captured.

根据 C++11 §5.1.2[expr.prim.lambda]/11:

Per C++11 §5.1.2[expr.prim.lambda]/11:

如果一个 lambda-expression 有一个关联的 capture-default 和它的 复合语句 odr-usesthis 或具有自动存储持续时间的变量且 odr-used 实体未被显式捕获,则称 odr-used 实体是隐式捕获.

If a lambda-expression has an associated capture-default and its compound-statement odr-uses this or a variable with automatic storage duration and the odr-used entity is not explicitly captured, then the odr-used entity is said to be implicitly captured.

您的 lambda 表达式具有关联的捕获默认值:默认情况下,您使用 [=] 按值捕获变量.

Your lambda expression has an associated capture default: by default, you capture variables by value using the [=].

当且仅当使用了变量(在术语已使用"的单一定义规则意义上)才是隐式捕获的变量.由于您在 lambda 表达式的主体(复合语句")中根本不使用 my_huge_vector,因此它不会被隐式捕获.

If and only if a variable is used (in the One Definition Rule sense of the term "used") is a variable implicitly captured. Since you don't use my_huge_vector at all in the body (the "compound statement") of the lambda expression, it is not implicitly captured.

继续第 5.1.2/14 节

To continue with §5.1.2/14

一个实体被复制捕获,如果

An entity is captured by copy if

  • 它是隐式捕获的,capture-default 是 = 或 if
  • 它是使用不包含 & 的捕获显式捕获的.
  • it is implicitly captured and the capture-default is = or if
  • it is explicitly captured with a capture that does not include an &.

由于您的 my_huge_vector 没有被隐式捕获,也没有被显式捕获,因此根本没有通过复制或引用捕获.

Since your my_huge_vector is not implicitly captured and it is not explicitly captured, it is not captured at all, by copy or by reference.

相关文章