In C++11, when are a lambda expression's bound variables supposed to be captured-by-value?

c++ lambda parameter
c++ pass lambda to function
c lambda return type
c lambda capture member variable
c template lambda
c lambda capture local variable
c++ lambda callback
lambda expression c++ msdn

I have a Visual Studio 2010 C++ program, the main function of which is:

vector<double> v(10);

double start = 0.0; double increment = 10.0;
auto f = [&start, increment]() { return start += increment; };
generate(v.begin(), v.end(), f);
for(auto it = v.cbegin(); it != v.cend(); ++it) { cout << *it << ", "; }

cout << endl << "Changing vars to try again..." << endl;
start = 15; increment = -1.5;
generate(v.begin(), v.end(), f);
for(auto it = v.cbegin(); it != v.cend(); ++it) { cout << *it << ", "; }
return 0;

When I compile this in MS Visual Studio, the first generate does what I expected, resulting in "10, 20, ... 100, ". The second does not; the lambda "sees" the change in start but not the change in increment, so I get "25, 35, ... 115, ".

MSDN explains that

The Visual C++ compiler binds a lambda expression to its captured variables when the expression is declared instead of when the expression is called. ... [T]he reassignment of [a variable captured by value] later in the program does not affect the result of the expression.

So my question is: is this standards-compliant C++11 behavior, or is it Microsoft's own eccentric implementation? Bonus: if it is standard behavior, why was the standard written that way? Does it have to do with enforcing referential transparency for functional programming?

With a lambda expression, the bound variables are captured at the time of declaration.

This sample will make it very clear: https://ideone.com/Ly38P

 std::function<int()> dowork()
 {
      int answer = 42;
      auto lambda = [answer] () { return answer; };

      // can do what we want
      answer = 666;
      return lambda;
 }

 int main()
 {
      auto ll = dowork();
      return ll(); // 42
 }

It is clear that the capture must be happening before the invocation, since the variables being captured don't even exist (not in scope, neither in lifetime) anymore at a later time.

Lambda expressions (since C++11), Microsoft Visual C++ 2010 (included in Visual Studio 2010). Basic Syntax and Elements for Lambda Expressions. A lambda expression is a  C++ 11 introduced lambda expression to allow us write an inline function which can be used for short snippets of code that are not going to be reuse and not worth naming. In its simplest form lambda expression can be defined as follows: [ capture clause ] (parameters) -> return-type { definition of method }.

It's bound at creation time. Consider:

#include <functional>
#include <iostream>

std::function<int(int)> foo;

void sub()
{
    int a = 42;
    foo = [a](int x) -> int { return x + a; };
}

int main()
{
    sub();
    int abc = 54;
    abc = foo(abc); // Note a no longer exists here... but it was captured by
                    // value, so the caller shouldn't have to care here...
    std::cout << abc; //96
}

There's no a here when the function is called -- there'd be no way for the compiler to go back and update it. If you pass a by reference, then you have undefined behavior. But if you pass by value any reasonable programmer would expect this to work.

Lambdas in C++11, Lambda expression in C++. C++ 11 introduced lambda expression to allow us write an inline function which can be used for short snippets of code that are not  In C++11 and later, a lambda expression—often called a lambda—is a convenient way of defining an anonymous function object (a closure) right at the location where it is invoked or passed as an argument to a function. Typically lambdas are used to encapsulate a few lines of code that are passed to algorithms or asynchronous methods.

I think you are confusing the mechanism of capture with the mechanism of variable passing. They are not the same thing even if they bear some superficial resemblance to one another. If you need the current value of a variable inside a lambda expression, capture it by reference (though, of course, that reference is bound to a particular variable at the point the lambda is declared).

When you 'capture' a variable, you are creating something very like a closure. And closures are always statically scoped (i.e. the 'capture' happens at the point of declaration). People familiar with the concept of a lambda expression would find C++'s lambda expressions highly strange and confusing if it were otherwise. Adding a brand new feature to a programming language that is different from the same feature in other programming languages in some significant way would make C++ even more confusing and difficult to understand than it already is. Also, everything else in C++ is statically scoped, so adding some element of dynamic scoping would be very strange for that reason as well.

Lastly, if capture always happened by reference, then that would mean a lambda would only be valid as long as the stack frame was valid. Either you would have to add garbage collected stack frames to C++ (with a huge performance hit and much screaming from people who are depending on the stack being largely contiguous) or you would end up creating yet another feature where it was trivially easy to blow your foot off with a bazooka by accident as the stack frame referenced by a lambda expression would go out of scope and you'd basically be creating a lot of invisible opportunities to return local variables by reference.

Lambda expression in C++, The problem. C++ includes useful generic functions like std::for_each and std::​transform , which can be very handy. Unfortunately they can also be quite  A lambda expression, sometimes also referred to as a lambda function or (strictly speaking incorrectly, but colloquially) as a lambda, is a simplified notation for defining and using an anonymous function object. Instead of defining a named class with an operator(), later making an object of that class,

Yes, it has to capture by value at the point because otherwise you could attempt to capture a variable (by reference for example) that no longer exists when the lambda/function is actually called.

The standard supports capturing both by value AND by reference to address both possible use cases. If you tell the compiler to capture by value it's captured at the point the lambda is created. If you ask to capture by reference, it will capture a reference to the variable which will then be used at the point the lambda is called (requiring of course that the referenced variable must still exist at the point the call is made).

What is a lambda expression in C++11?, Learn everything you ever wanted to know about lambda functions in C++11. If you have a simple return expression, the compiler will deduce the type of the  In C++11 and later, a lambda expression—often called a lambda—is a convenient way of defining an anonymous function object (a closure) right at the location where it is invoked or passed as an argument to a function.

C++11 - Lambda Closures, the Definitive Guide, Danny Kalev shows you how to read lambda expressions and use them in C++​11 applications. Originally, functional programming in C consisted  C++ has introduced lambda expressions in C++11 to allow creating anonymous function.

C++11 Tutorial: Lambda Expressions, C++ STL includes useful generic functions like std::for_each. Unfortunately they can also be quite cumbersome to use, particularly if the functor  In C++11, if the compiler can deduce the return value of the lambda function, it will do it rather than force you to include it. In this case, the compiler knows the function returns nothing. Next we have the body, printing out "Hello World".

What is a lambda expression in C++11?, auto declarations, range-based for loops, lambda expressions, and rvalue references change the face of C++, to say nothing of the new concurrency features. And  The lambda expression is a prvalue expression of unique unnamed non-union non-aggregate class type, known as closure type, which is declared (for the purposes of ADL) in the smallest block scope, class scope, or namespace scope that contains the lambda expression.

Comments
  • Where is the problem? You capture start by reference but increment by value.
  • K-ballo: the question is when exactly this capture happens. In a normal function declaration, that happens when the function is called, not declared... Although the latter wouldn't make sense for a normal function, it could for a lambda.
  • It has to do with (a) copy semantics (b) thread safety
  • Consider that you can pass your lambda out of the current scope, and call it from there. At that point, increment does not exist any more, so how can the compiler possibly bind it when the function is called?
  • Yes, this behavior is in accordance with the C++11 spec.
  • I think you frankly oversimplified here. The lambda object exists on the stack and the content of its capture as well. It is copied into the function object at the point of return, using function's template copy constructor, which operates a type erasure mecanism, and allocates the callable copy on the heap.