Answers
Q: What is a lambda expression in C++11?
A: Under the hood, it is the object of an autogenerated class with an overloaded operator() const. Such an object is called a closure and is created by the compiler. This 'closure' concept is similar to the 'bind' concept from C++11, but lambdas typically generate more performant code. Also, calls through closures (instead of typical functions) allow full inlining.
Q: When would I use one?
A: When you want to define "simple and small logic" and ask the compiler to perform generation from previous question. You give a compiler some expressions which you want to be inside operator(). All the other stuff, the compiler will generate for you.
Q: What class of problem do lambdas solve that wasn't possible to solve prior to their introduction?
A: Lambdas are more of a syntactical sugar (i.e., code meant for ease-of-use) like "operator overloading" instead of having to make entire functions for custom add, subtract operations... Lambdas save more lines of unneeded code to wrap 1-3 lines of real logic to some classes, and etc.! Some engineers think that if the number of lines is smaller, then there is a lesser chance to make errors in it (I'm think so too).
Example of usage
auto x = [=](int arg1){printf("%i", arg1); }; // Note the ending semicolon after {}. void(*f)(int) = x; // ^Create function pointer f that takes parameter `int`. // ^See point 4.1 below under "Extras about Lambdas". f(1); // Call function f with parameter `int 1` x(1); // Call function x with parameter `int 1`
Extras about lambdas, not covered by question. Ignore this section if you're not interested
1. Captured values. What you can capture
1.1. You can reference to a variable with static storage duration in lambdas. They all are captured.
1.2. You can use lambda to capture values "by value". In such case, captured vars will be copied to the function object (closure).
[captureVar1,captureVar2](int arg1){} //Modification of either captured value inside the Lambda //will *not* modify the value outside the Lambda too, //meaning a variable outside the Lambda that is also named //captureVar1 will be unaffected by what happens inside the Lambda. //I.e., Variable Shadowing will occur.
1.3. You can capture by reference. & -- in this context mean reference, not pointers.
[&captureVar1,&captureVar2](int arg1){} //Modification of either capture value inside the Lambda //will modify the value outside the Lambda too!
1.4. Notation exists to capture all non-static vars by value, or by reference
[=](int arg1){} // capture all not-static vars by value [&](int arg1){} // capture all not-static vars by reference
1.5. Notation exists to capture all non-static vars by value, or by reference, while overriding specific variables to be specifically by-value or by-reference Examples: Capture all not-static vars by value, but by reference capture Param2
[=,&Param2](int arg1){}
Capture all not-static vars by reference, but by value capture Param2
[&,Param2](int arg1){}
2. Return type deduction
2.1. Lambda return type can be deduced if lambda is one expression. Or you can explicitly specify it.
[=](int arg1)->trailing_return_type{return trailing_return_type();}
If lambda has more than one expression, then return type must be specified via trailing return type. Also, similar syntax can be applied to auto functions and member-functions
3. Captured values. What you cannot capture
3.1. You can capture only local vars, not member variables of the object.
4. Сonversions
4.1 !! Lambda is not a function pointer and it is not an anonymous function, but capture-less lambdas can be implicitly converted to a function pointer.
P.s.
More about lambda grammar information can be found in Working draft for Programming Language C++ #337, 2012-01-16, 5.1.2. Lambda Expressions, p.88
In C++14 an extra feature, named as "init capture", has been added. It allows you to arbitrarily perform declaration of closure data members:
auto toFloat = [](int value) { return float(value);}; auto interpolate = [min = toFloat(0), max = toFloat(255)] (int value)->float { return (value - min) / (max - min);};