До сих пор я слышал о:
- Лямбда-исчисление
- Лямбда-программирование
- Лямбда-выражения
- Лямбда-функции
Что, похоже, связано с функциональным программированием ...
По всей видимости, он будет интегрирован в C ++ 1x, поэтому я мог бы лучше понять это сейчас:
http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions
Может кто-нибудь кратко определить, что такое лямбда-вещи, и указать, где это может быть полезно?
c++
functional-programming
lambda
jokoon
источник
источник
Ответы:
Лямбда-исчисление - это вычислительная модель, изобретенная Алонзо Черчем в 30-х годах. Синтаксис и семантика большинства функциональных языков программирования прямо или косвенно основаны на лямбда-исчислении.
Лямбда-исчисление в своей основной форме имеет две операции: абстракция (создание (анонимной) функции) и приложение (применение функции). Абстракция выполняется с помощью оператора λ, дающего имя лямбда-исчислению.
Анонимные функции часто называют «лямбда-выражениями», «лямбда-функциями» или «лямбда-выражениями», потому что, как я уже говорил выше, λ был символом для создания анонимных функций в лямбда-исчислении (а слово
lambda
используется для создания анонимных функций во многих lisp). на основе языков по той же причине).Это не часто используемый термин, но я предполагаю, что это означает программирование с использованием анонимных функций или программирование с использованием функций более высокого порядка.
Немного больше информации о лямбдах в C ++ 0x, их мотивации и о том, как они связаны с указателями на функции (вероятно, многое из этого повторяет то, что вы уже знаете, но я надеюсь, что это поможет объяснить мотивацию лямбд и то, как они отличаются из указателей функций):
Указатели на функции, которые уже существовали в C, весьма полезны, например, для передачи функции сравнения в функцию сортировки. Однако есть пределы их полезности:
Например, если вы хотите отсортировать вектор векторов по
i
элементу th каждого вектора (гдеi
это параметр времени выполнения), вы не можете решить это с помощью указателя на функцию. Функция, которая сравнивает два вектора по ихi
th-элементу, должна принимать три аргумента (i
и два вектора), но для функции сортировки потребуется функция, принимающая два аргумента. Нам нужен способ как-то предоставить аргументi
функции перед передачей в функцию сортировки, но мы не можем сделать это с простыми функциями Си.Чтобы решить эту проблему, C ++ ввел понятие «функциональные объекты» или «функторы». Функтор - это в основном объект, у которого есть
operator()
метод. Теперь мы можем определить классCompareByIthElement
, который принимает аргументi
в качестве аргумента конструктора, а затем принимает два вектора для сравнения в качестве аргументовoperator()
метода. Чтобы отсортировать вектор векторов поi
th-му элементу, мы можем теперь создатьCompareByIthElement
объект сi
аргументом и затем передать этот объект в функцию сортировки.Поскольку функциональные объекты являются просто объектами, а не технически функциями (даже если они должны вести себя как они), вы не можете сделать указатель на функцию указателем на функциональный объект (вы, конечно, можете иметь указатель на функциональный объект, но это будет иметь тип как
CompareByIthElement*
и, следовательно, не будет указателем на функцию).Большинство функций в стандартной библиотеке C ++, которые принимают функции в качестве аргументов, определяются с помощью шаблонов, чтобы они работали как с указателями на функции, так и с объектами функций.
Теперь к лямбдам:
Определение целого класса для сравнения по
i
элементу th немного многословно, если вы собираетесь использовать его только один раз для сортировки вектора. Даже в том случае, когда вам нужен только указатель на функцию, определение именованной функции является субоптимальным, если она используется только один раз, потому что а) она загрязняет пространство имен и б) функция обычно будет очень маленькой и на самом деле хорошая причина абстрагировать логику в ее собственную функцию (кроме того, что вы не можете иметь указатели на функции без определения функции).Таким образом, чтобы исправить это лямбды были введены. Лямбды - это функциональные объекты, а не указатели на функции. Если вы используете лямбда-литерал
[x1, x2](y1,y2){bla}
, создается код, который в основном делает следующее:x1
иx2
) и aoperator()
с аргументами (y1
иy2
) и теломbla
.x1
иx2
значения переменныхx1
и вx2
настоящее время в области видимости.Таким образом, лямбды ведут себя как объекты функций, за исключением того, что вы не можете получить доступ к классу, который сгенерирован для реализации лямбды, кроме как с использованием лямбды. Следовательно, любая функция, которая принимает функторы в качестве аргументов (в основном это означает любую не-C-функцию в стандартной библиотеке), будет принимать лямбда-выражения, но любая функция, принимающая только указатели на функции, не будет.
источник
std::sort
на функции ( например), вы сможете вместо этого использовать анонимные функции. Однако при определении функции, которая должна принимать анонимную функцию в качестве аргумента, вам нужно либо использовать шаблон, либо использоватьstd::function
в качестве типа аргумента.+1
от меня.По сути, лямбда-функции - это функции, которые вы создаете «на лету». В C ++ 1x их можно использовать для улучшения поддержки функционального программирования:
Это примерно приведет к коду, похожему на этот:
Если вам нужен
some_functor
только один вызовstd::for_each()
, то у этой лямбда-функции есть несколько преимуществ:источник
Лямбда-функция - это другое имя для анонимной функции - по сути, функция без имени.
Обычно вы используете это в языках, где вам нужно будет использовать функцию только один раз. Например вместо
а затем передать эту функцию в другую функцию, как так
С лямбдой вы бы просто сделали
источник