1

I am just wondering how to write a Lambda function in C++ that 'remembers' a value passed into it for when it is called next time? Specifically I am thinking of the i=i syntax from Python as follows:

funs = [(lambda i=i: i) for i in range(10)]

Such that if the following code is run:

for i in range(len(funs)):
    print funs[i]()

The result is:

0
1
4
9
16

I was also wondering what the technical name (if one exists for this) would be? (I know that if I knew the answer to the second question I could just Google for the solution...)

lachy
  • 1,833
  • 3
  • 18
  • 27
  • Remembers in the body of the function? Remembers when the function is called next time? Please clarify. – R Sahu Feb 23 '17 at 05:15
  • 1
    @RSahu He's talking about how Python can use default argument captures to retain values, and whether C++ lambdas have a similar nuance. In case anyone is unfamiliar with this concept, [great question about them here](http://stackoverflow.com/questions/2295290/what-do-lambda-function-closures-capture-in-python). The second answer amplifies what he's describing. – WhozCraig Feb 23 '17 at 05:17
  • Thanks @WhozCraig for the clarification and the link. – R Sahu Feb 23 '17 at 05:29
  • 1
    As an aside, captured values are not mutable by default - which is generally a good thing - but can be made such with the mutable keyword before the brackets. This can sometimes be useful for putting a use counter in a lambda. – doug Feb 23 '17 at 08:00

1 Answers1

5

You are probably looking for pass-by-value variable capture in lambdas. It's the default in C++. Example:

#include <functional>
#include <iostream>
#include <vector>

int main() {
  std::vector<std::function<void(void)>> foo;
  for (int i = 0; i < 10; i++)
    foo.push_back(
      [i](){ std::cout << i << "\n"; }
    );
  for (const auto &f : foo)
    f();
}

Will print numbers from 0 to 9.

Note the [i] syntax. In C++, you should list all local variables which will be "seen" by the lambda function. If you simply list variable here, its value is copied. If you list it with & (like [&i]), then it's passed by reference. Obviously, in the latter case the lambda will become invalid as the capture variable goes out of the scope.

Variables are captured at the moment of lambda creation.

yeputons
  • 8,478
  • 34
  • 67