Лямбда-функция – вариант реализации функциональных объектов в языке С++11, обязанный своим названием λ-исчислению – математической системе определения и применения функций, в которой аргументом одной функции может быть другая функция. Лямбда-функции в основном определяются в точке их применения. Лямбда-функции могут использоваться всюду, где требуется передача вызываемому объекту функции соответствующего типа.
Лямбда-функции могут использовать внешние по отношению к ней самой племенные, образующие замыкание такой функции. В С++ лямбда-функции определяются как:
[]() { }
Где []
- лист “захваченных переменных”, ()
- параметры функции, {}
- тело функции
Например:
bool foo(int x) { return x % m == 0; }
эквивалентно
[] (int x) { return x % m == 0; }
При преобразовании функции языка C++ в лямбда-функцию необходимо учитывать, что имя функции заменяется в лямбда-функции квадратными скобками []
, а возвращаемый тип:
return expr;
[](int x) -> int { int y = x; return x – y; }
Рассмотрим следующую функцию:
#include<iostream>
#include<vector>
using namespace std;
int main() {
vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8};
vector<int> odd;
for (int i = 0; i < v.size(); ++i) {
if (v[i] % 2 == 1) {
odd.push_back(v[i]);
}
}
for (int i = 0; i < odd.size(); ++i) {
cout << odd[i] << endl;
}
return 0;
}
Можно заменить на:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main() {
vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8};
vector<int> odd;
copy_if(v.begin(), v.end(), std::back_inserter(odd), [](int i) { return i % 2 == 1; });
for (int i = 0; i < odd.size(); ++i) {
cout << odd[i] << endl;
}
return 0;
}
Любую анонимную лямбда-функцию можно сделать именной:
auto isOdd = [](int i) { return i % 2 == 1; };
copy_if(v.begin(), v.end(), std::back_inserter(odd), isOdd);
Также с помощью лямбда-функции можно менять значение на месте (in-place) как показано в примере ниже:
string s = "hello";
transform(s.begin(), s.end(), s.begin(), [](unsigned char c) -> unsigned char { return toupper(c); });
cout << s;
Внешние по отношению к лямбда-функции переменные, определенные в одной с ней области видимости, могут захватываться лямбда-функцией и входить в ее замыкание. При этом в отношении доступа к переменным действуют следующие правила:
Например, в примере ниже показано использование лямбда-функции для подсчета количества четных элементов в векторе (без замыкания):
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main() {
vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8};
int countN = count_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; });
cout << countN;
return 0;
}
Этот же пример можно переписать использую замыкание:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main() {
vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8};
int countN = 0;
for_each(v.begin(), v.end(), [&countN](int x) { countN += x % 2 == 0; });
cout << countN;
return 0;
}