Ответ 1
Это то, что называется Обобщенный захват лямбда, и да, это С++ 14.
В основном это позволяет вам создать новую переменную как часть списка захвата.
Текст по ссылке:
В С++ 11 lambdas не мог (легко) захватить движением. В С++ 14 мы имеем обобщенный лямбда-захват, который решает не только эту проблему, но позволяет определить произвольные новые локальные переменные в лямбда объект. Например:
auto u = make_unique<some_type>( some, parameters ); // a unique_ptr is move-only go.run( [ u=move(u) ] { do_something_with( u ); } ); //move the unique_ptr into the lambda
В приведенном выше примере мы сохранили имя переменной
u
то же самое внутри лямбда. Но не были ограниченный этим... мы можем переименовать переменные:go.run( [ u2=move(u) ] { do_something_with( u2 ); } ); // capture as "u2"
И мы можем добавить произвольное новое состояние к лямбда-объекту, потому что каждый захват создает новую локализованную локальную переменную внутри лямбда:
int x = 4; int z = [&r = x, y = x+1] { r += 2; // set x to 6; "R is for Renamed Ref" return y+2; // return 7 to initialize z }(); // invoke lambda
В вашем конкретном случае у вас есть лямбда, которая возвращает лямбду. Вложенный лямбда захватывает f
(который был только параметром в родительском лямбда), используя этот новый синтаксис.