Answer
The compiler turns a lambda into an unnamed class (closure type) with a member operator() holding the body, and member variables for the captures (copies for by-value, references for by-reference). A captureless lambda is convertible to a plain function pointer. Because each lambda has a unique type, they're typically stored via auto or std::function.
// [x](int y){return x+y;} roughly becomes:
struct __lambda { int x; int operator()(int y) const { return x+y; } };Real-world example Understanding that a lambda is a class with captured members explains why capture-by-reference can dangle.