Во-первых:
int lf = [/*captures*/]() {/*body*/};
- неверный код, он должен быть
// case 1. lambda is automatic
auto lf = [/*captures*/]() {/*body*/}; // closure object
или (при условии, что лямбда возвращает что-то, совместимое с int
)
// case 2. lambda is temporary
int lf = [/*captures*/]() {/*body*/} (); /* calling object created */
лямбда-выражение - это сокращенное обозначение для создания объекта с уникальным классом (очень упрощенное, вы должны посмотреть стандартную или языковую ссылку для полного описания):
class Closure {
/* members storing captured values or references */
public:
return-type operator( /* argument list*/ ) { /*body*/ };
}
В первом случае лямбда будет хранится в стеке, во втором случае это временный объект.
Таким образом, лямбда со списком захвата будет хранить такой объект, то есть все захваченные значения именно там, где вы указали ему хранить лямбда-объект, в вашем случае это автомат c хранилище (так называемый, «стек»). Использование лямбды без захвата ничем не отличается от объявления функции и использования указателя на нее, с ней не связано хранилище, и ее можно привести к указателю на функцию.