#cpp #lambda #лямбда_выражение
Изучая лямбда-выражения, столкнулся со стойким непониманием и безрезультативными
попытками самостоятельно разобраться с передачей аргументов лямбда выражениям.
Я знаю, что лямбда может принимать аргумент, если после объявления или где-либо после
написать скобки: (arg);.
Также лямбда может захватывать значения перемемнных [=], [x] и т.д.
Однако, как лямбда получает аргумент, имея подобную конструкцию:
[](int n){/*do something*/},
если нигде после её объявления явно не вызываются "скобки со значением", нет доступных
из лямбды внешних ссылок, и она ничего не захватывает?
Подскажие, как передаются аргументы лямбда-выражениям в подобных случаях?
using namespace std;
int main()
{
list numbers;
numbers.push_back(13);
numbers.push_back(42);
numbers.push_back(99);
const list::const_iterator result =
find_if(numbers.begin(), numbers.end(),[](int n) { return (n % 2) == 0; });
if (result != numbers.end()) {
cout << "The first even number in the list is " << *result << "." << endl;
} else {
cout << "The list contains no even numbers." << endl;
}
}
Как я понмаю, лямбда-выражение имеет параметр (int n), однако не вижу где лямбда
принимает этот аргумент. И не понимаю как он мог бы передаваться неявно.
...
using namespace std;
int main()
{
vector srcVec;
for (int val = 0; val < 10; val++)
{
srcVec.push_back(val);
}
int result =
count_if(srcVec.begin(), srcVec.end(), [] (int _n)
{
return (_n % 2) == 0;
});
cout << result << endl;
return EXIT_SUCCESS;
}
Как происходит подобная "неявная" передача аргументов лямбда-выражениям, имеющим
параметр, но не обращающихся к внешним переменным самостоятельно через завхват или
область видимости?
Может быть я не понимаю какого-то банального принципа, который совершенно тривиален,
но был мной упущен? Спасибо.
Ответы
Ответ 1
Функция find_if, count_if 3-м аргументом принимают унарный предикат(UnaryPredicat) - функция, которая на вход принимает один аргумент и возвращает тип bool. Требования к предикатной функции. Внутренняя реализация этих функций из стандартной библиотеки вызывает этот унарный предикат, передавая ей в качестве аргумента текущее "тестируемое значение" из коллекции. Унарный предикатом может быть как лямбда-функция, так и любой реализованный самостоятельно функтор.Ответ 2
Однако, как лямбда получает аргумент, имея подобную конструкцию: [](int n){/*do something*/}, если нигде после её объявления явно не вызываются "скобки со значением"? find_if(numbers.begin(), numbers.end(),[](int n) { return (n % 2) == 0; }); На самом деле здесь все просто. Лямбду вызывает find_if, то есть эти "скобки со значением" находятся где-то внутри find_if. Вот пример реализации find_if с cppreference: templateInputIt find_if(InputIt first, InputIt last, UnaryPredicate p) { for (; first != last; ++first) { if (p(*first)) // <--- Вот они скобки (вызов лямбды) { return first; } } return last; }
Комментариев нет:
Отправить комментарий