Разница между вашей первой и второй лямбдой и между третьей и четвертой лямбдой заключается в том, что вы либо явно, либо не указываете тип возвращаемого значения.Здесь это приводит к идентичным функциям.
Разница между вашими первыми двумя лямбдами и лямбдами три и четыре - захват.Но ваши примеры не подходят для иллюстрации эффектов захвата.Посмотрите на следующий код ( live demo ).
int main()
{
double v = 100.0;
auto lam1= [](double val) { return MyFunction(val, 1.0, 2.0); }; //A
auto lam2= [v](double val) { return MyFunction(v, 1.0, 2.0); }; //B
auto lam3= [&v](double val) { return MyFunction(v, 1.0, 2.0); }; //C
FunctionWrapper( lam1, v++ ); //1
FunctionWrapper( lam2, v++ ); //2
FunctionWrapper( lam3, v++ ); //3
std::cout << "v: " << v << '\n';
}
Хотя lam1
ничего не захватывает, lam2
захватывает v
по значению и lam3
захватывает v
по ссылке.Выход трех вызовов FunctionWrapper
составляет 103, 103, 106, соответственно.Это потому, что хотя v
было изменено в строке //1
, в строке //2
используется старое значение.То есть захват по значению означает, что значение v
сохраняется в то время, когда lam2
инициализируется в строке //B
, сохраняется в lam2
.С другой стороны, в строке //3
используется текущее значение v
.Это потому, что lam3
содержит ссылку на v
.