#cpp #lambda #лямбда_выражение
Изучая лямбда-выражения, столкнулся со стойким непониманием и безрезультативными попытками самостоятельно разобраться с передачей аргументов лямбда выражениям. Я знаю, что лямбда может принимать аргумент, если после объявления или где-либо после написать скобки: (arg);. Также лямбда может захватывать значения перемемнных [=], [x] и т.д. Однако, как лямбда получает аргумент, имея подобную конструкцию: [](int n){/*do something*/}, если нигде после её объявления явно не вызываются "скобки со значением", нет доступных из лямбды внешних ссылок, и она ничего не захватывает? Подскажие, как передаются аргументы лямбда-выражениям в подобных случаях? using namespace std; int main() { listnumbers; 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; }
Комментариев нет:
Отправить комментарий