С++ Lambdas: список списка захвата и список параметров
Согласно стандарту С++ 11, лямбда-выражения могут использовать переменные в охватывающей области, с помощью списка захвата, списка параметров или обоих.
Итак, рассмотрим две версии одного и того же кода.
1) С захватом
int x = 4;
cout << "With capture : Factorial of " << x << " = " << [x]() // <= Capture
{
int r = 1;
for (int i = x; i > 1; i--) r = r * i;
return r;
}() << endl;
2) С параметром
int x = 4;
cout << "With parameter: Factorial of " << x << " = " << [](int x) // <= Parameter
{
int r = 1;
for (int i = x; i > 1; i--) r = r * i;
return r;
}(x) << endl;
Вывод:
With capture : Factorial of 4 = 24
With parameter: Factorial of 4 = 24
Так как мы можем передавать параметры в lambdas в списке параметров (как и в случае любой функции С++), зачем нам нужен список захвата?
Может ли кто-нибудь показать мне случаи, когда список параметров не работает, и только список захвата делает?
Ответы
Ответ 1
Например, используя stl-алгоритмы:
std::vector<int> items;
int factor;
auto foundItem = std::find_if(items.begin(), items.end(),
[&factor](int const& a)
{
return a * factor == 100;
});
В этом случае вы вызываетесь в лямбда для каждого элемента в контейнере, и вы возвращаете, если значение, умноженное на захваченный коэффициент, равно 100.
Код не имеет особого смысла, он просто показывает вам пример, в котором содержатся списки захвата и параметров.
Ответ 2
Дело в том, что с захватом вы можете сохранить состояние (как написанный вручную класс с помощью оператора()) в функционально подобном объекте. @dau_sama дает хороший ответ. Вот еще один пример:
#include <iostream>
using namespace std;
int main() {
const auto addSome = [](double some){
return [some](double val){ return some+val; } ;
};
const auto addFive = addSome(5);
std::cout << addFive(2) << std::endl;
}