Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it a bad practice to always capture all in a lambda expression? [duplicate]

std::function<int()> void f1()
{
    int a, b, c, d, ..., x, y, z;

    return [=] { return a + b + c; };
}

vs.

std::function<int()> void f2()
{
    int a, b, c, d, ..., x, y, z;

    return [a, b, c] { return a + b + c; };
}

Needless to say, the former is shorter, handier, and more elegant than the latter.

However, I still worry:

From the performance viewpoint, is the latter always better than the former?

Does the standard guarantee a lambda expression captures the necessary variables only? i.e. In the former example, only a, b, c are captured, the unused variables d, ..., x, y, z are not.

like image 200
xmllmx Avatar asked Sep 26 '13 01:09

xmllmx


2 Answers

The standard guarantees that if you do a default capture, the only variables that will be captured by that default capture from the surrounding environment are those that you actually use inside the lambda.

As such, specifying individual variables to capture acts as documentation of what you expect to use, but should never affect performance.

For anybody who cares, the exact wording from the standard is (§5.1.2/11, 12):

11 If a lambda-expression has an associated capture-default and its compound-statement odr-uses (3.2) 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; such entities shall be declared within the reaching scope of the lambda expression. [Note elided]

12 An entity is captured if it is captured explicitly or implicitly. [...]

Summary

An implicit capture specification ([=] or [&]) will only capture variables that are used in the lambda, so implicit vs. explicit capture should never affect performance.

like image 141
Jerry Coffin Avatar answered Oct 09 '22 15:10

Jerry Coffin


Not really... most other languages don't require (or even allow) you to specify what you want to capture either.

Let the compiler infer what's necessary when it can.
It won't make a mistake, and it won't "accidentally" capture something unused inside the lambda.
If you want to be explicit (sometimes that makes sense), that's what traditional functors are perfect for.

like image 4
user541686 Avatar answered Oct 09 '22 16:10

user541686