23

Can somebody please provide some insights on this? Is the lambda capturing external variables, or is the outside world capturing values produced by the lambdas? What does it mean for a certain variable to be captured?

Praetorian
  • 106,671
  • 19
  • 240
  • 328
Baron Yugovich
  • 3,843
  • 12
  • 48
  • 76
  • I don't understand what you mean by *or is the outside world capturing values produced by the lambdas*, but maybe [this](https://stackoverflow.com/a/23499673/241631) answers your question. – Praetorian Aug 13 '15 at 04:08
  • It literally means to copy objects, (or references to objects) into the scope of the function. The function literally *captures* part of the environment from which it was created. This gives it context data to operate with. – Galik Aug 13 '15 at 04:28

3 Answers3

23

The lambda is capturing an outside variable.

A lambda is a syntax for creating a class. Capturing a variable means that variable is passed to the constructor for that class.

A lambda can specify whether it's passed by reference or by value. For example:

[&] { x += 1; }       // capture by reference
[=] { return x + 1; } // capture by value

The first produces a class roughly like this:

class foo { 
    int &x;
public:
    foo(int &x) : x(x) {}
    void operator()() const { x += 1; }
};

The second produces a class something like this:

class bar {
    int x;
public:
    bar(int x) : x(x) {}
    int operator()() const { return x + 1; }
};

As with most uses of references, capturing by reference can create a dangling reference if the closure (the object of the class created by the lambda expression) out-lives the object that was captured.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • 1
    "A lambda is a syntax for creating a class." Not necessarily. – RamblingMad Aug 13 '15 at 05:45
  • @CoffeeandCode: Oh? What are the alternatives? – Jerry Coffin Aug 13 '15 at 05:46
  • 3
    `[](){/* ... body ... */}` is convertible to a plain function pointer `void(*)()`, so could be implemented as a free-standing function. Anyway, the compiler could do all sorts of trickery for capturing-lambdas. It could define functions that take pointers to local variables and dereference them for capture. It could simply append `int x = /* captured value */` to the lambdas body in some cases. There are many ways it could be implemented other than a class with `operator()()`. It's really up to the implementation. – RamblingMad Aug 13 '15 at 05:55
  • 7
    @CoffeeandCode: Hmm...the standard seems to disagree (§5.1.2/3): "The type of the lambda-expression (which is also the type of the closure object) is a **unique, unnamed nonunion class type** — called the closure type — whose properties are described below." It's certainly true that the usual "as if" rule applies to the implementation of that class, but they don't make it any less a class. – Jerry Coffin Aug 13 '15 at 06:03
  • 4
    @CoffeeandCode Yeah, it's a class with a conversion operator to function pointer – M.M Aug 13 '15 at 06:05
7

Jerry Coffin gave you detailed response,I agree that lambda is syntax for creating a class.There are bunch of options about the way variables are captured and how.List of options:

[]  Capture nothing (or, a scorched earth strategy?)
[&] Capture any referenced variable by reference
[=] Capture any referenced variable by making a copy
[=, &foo]   Capture any referenced variable by making a copy, but capture variable foo by reference
[bar]   Capture bar by making a copy; don't copy anything else
[this]  Capture the this pointer of the enclosing class
Richard Rublev
  • 7,718
  • 16
  • 77
  • 121
3

Lambda captures variables which it otherwise will not have access to. One can specify how A lambda should capture a variable .i.e value,reference . This has been explained really well here In lambda functions syntax, what purpose does a 'capture list' serve?

Community
  • 1
  • 1