Question

I know that capture lists make variables available inside a lambda function body like so:

int pos(0);
std::function<void()> incPos = [&pos](){ ++pos; };
incPos(); //pos is now 1

But how does that capturing actually work on compiler level? Where are the captured addresses or captured values stored?

Was it helpful?

Solution

Each lambda expression generates a unique function object (closure) that stores the captured variables as data members. For instance, the lambda expression in your code would be transformed into something like this by the compiler:

struct __uniquely_named_lambda
{
  __uniquely_named_lambda(int& pos)
  : pos(pos) {}
  int& pos;

  void operator()() const
  { ++pos; }
};

Invoking the lambda is simply a call to operator().

The data member is a reference since you captured by reference. If you captured by value it would be a plain int. Also note that generated operator() is const by default. This is why you cannot modify captured variables unless you use the mutable keyword.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top