In recent days, I've twice found myself explaining the difference between lambdas and closures in C++11, so I figured it was time to write it up.
The term "lambda" is short for lambda expression, and a lambda is just that: an expression. As such, it exists only in a program's source code. A lambda does not exist at runtime.
The runtime effect of a lambda expression is the generation of an object. Such objects are known as closures.
Given
auto f = [&](int x, int y) { return fudgeFactor * (x + y); };
the blue expression to the right of the "=" is the lambda expression (i.e., "the lambda"), and the runtime object created by that expression is the closure.
You could be forgiven for thinking that, in this example, f was the closure, but it's not. f is a copy of the closure. The process of copying the closure into f may be optimized into a move (whether it is depends on the types captured by the lambda), but that doesn't change the fact that f itself is not the closure. The actual closure object is a temporary that's typically destroyed at the end of the statement.
The distinction between a lambda and the corresponding closure is precisely equivalent to the distinction between a class and an instance of the class. A class exists only in source code; it doesn't exist at runtime. What exists at runtime are objects of the class type. Closures are to lambdas as objects are to classes. This should not be a surprise, because each lambda expression causes a unique class to be generated (during compilation) and also causes an object of that class type--a closure--to be created (at runtime).
Scott
PS - I noted above that a closure is typically destroyed at the end of the statement in which it is created. The exception to this rule is when you bind the closure to a reference. The simplest way to do that is to employ a universal reference,
auto&& rrefToClosure = [&](int x, int y) { return fudgeFactor * (x + y); };
but binding it to an lvalue-reference-to-const will also work:
const auto& lrefToConstToClosure = [&](int x, int y) { return fudgeFactor * (x + y); };