Do tej pory słyszałem o:
- Rachunek Lambda
- Programowanie lambda
- Wyrażenia lambda
- Funkcje Lambda
Co wydaje się mieć związek z programowaniem funkcjonalnym ...
Najwyraźniej zostanie zintegrowany z C ++ 1x, więc lepiej zrozumiem teraz:
http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions
Czy ktoś może krótko zdefiniować, czym są rzeczy lambdas i podać, gdzie mogą być przydatne?
Odpowiedzi:
Rachunek lambda to model obliczeniowy wynaleziony przez Alonzo Church w latach 30. Składnia i semantyka większości funkcjonalnych języków programowania są bezpośrednio lub pośrednio inspirowane rachunkiem lambda.
Rachunek lambda w najbardziej podstawowej formie ma dwie operacje: Abstrakcję (tworzenie (anonimowej) funkcji) i aplikację (zastosowanie funkcji). Abstrakcja jest wykonywana za pomocą operatora λ, nadając rachunku lambda swoją nazwę.
Funkcje anonimowe są często nazywane „lambdami”, „funkcjami lambda” lub „wyrażeniami lambda”, ponieważ, jak powiedziałem powyżej, λ było symbolem tworzenia funkcji anonimowych w rachunku lambda (a słowo
lambda
to jest używane do tworzenia funkcji anonimowych w wielu seplenieniach języki oparte na tym samym celu).Nie jest to termin powszechnie używany, ale zakładam, że oznacza to programowanie przy użyciu anonimowych funkcji lub programowanie przy użyciu funkcji wyższego rzędu.
Trochę więcej informacji na temat lambd w C ++ 0x, ich motywacji i ich związku ze wskaźnikami funkcyjnymi (wiele z nich jest prawdopodobnie powtórzeniem tego, co już wiesz, ale mam nadzieję, że pomoże to wyjaśnić motywację lambdas i ich różnice ze wskaźników funkcji):
Wskaźniki funkcji, które już istniały w C, są bardzo przydatne np. Do przekazania funkcji porównawczej do funkcji sortującej. Istnieją jednak ograniczenia ich przydatności:
Na przykład, jeśli chcesz posortować wektor wektorów według
i
elementu th każdego wektora (gdziei
jest parametrem czasu wykonywania), nie możesz tego rozwiązać za pomocą wskaźnika funkcji. Funkcja, która porównuje dwa wektory według ichi
elementu, musiałaby wziąć trzy argumenty (i
i dwa wektory), ale funkcja sortująca wymagałaby funkcji przyjmującej dwa argumenty. Potrzebujemy sposobu, aby jakoś dostarczyć argumenti
do funkcji przed przekazaniem jej do funkcji sortowania, ale nie możemy tego zrobić za pomocą zwykłych funkcji C.Aby rozwiązać ten problem, C ++ wprowadził pojęcie „obiektów funkcji” lub „funktorów”. Funktor to w zasadzie obiekt posiadający
operator()
metodę. Teraz możemy zdefiniować klasęCompareByIthElement
, która przyjmuje argumenti
jako argument konstruktora, a następnie przyjmuje dwa wektory do porównania jako argumenty dooperator()
metody. Aby posortować wektor wektorów wedługi
tego elementu, możemy teraz utworzyćCompareByIthElement
obiekti
jako argument, a następnie przekazać ten obiekt do funkcji sortowania.Ponieważ obiekty funkcyjne są tylko obiektami, a nie funkcjami technicznymi (nawet jeśli mają się tak zachowywać), nie można ustawić wskaźnika funkcji na obiekt funkcji (można oczywiście mieć wskaźnik na obiekt funkcji, ale to miałby typ podobny,
CompareByIthElement*
a zatem nie byłby wskaźnikiem funkcji).Większość funkcji w standardowej bibliotece C ++, które przyjmują funkcje jako argumenty, są definiowane przy użyciu szablonów, dzięki czemu działają one ze wskaźnikami funkcji oraz obiektami funkcji.
Teraz do lambdas:
Zdefiniowanie całej klasy do porównania za pomocą
i
elementu th jest nieco zbyt szczegółowe, jeśli kiedykolwiek użyjesz jej tylko raz do posortowania wektora. Nawet w przypadku, gdy potrzebujesz tylko wskaźnika funkcji, zdefiniowanie nazwanej funkcji jest nieoptymalne, jeśli zostanie użyte tylko raz, ponieważ a) zanieczyszcza przestrzeń nazw ib) funkcja zwykle będzie bardzo mała i tak naprawdę nie ma dobry powód do wyodrębnienia logiki we własną funkcję (poza tym, że nie można mieć wskaźników funkcji bez zdefiniowania funkcji).Aby to naprawić, wprowadzono lambdas. Lambdy są obiektami funkcyjnymi, a nie wskaźnikami funkcji. Jeśli użyjesz literału typu lambda,
[x1, x2](y1,y2){bla}
generowany jest kod, który zasadniczo wykonuje następujące czynności:x1
ix2
) i anoperator()
z argumentami (y1
iy2
) i treściąbla
.x1
orazx2
wartości zmiennychx1
ix2
obecnie w zasięgu.Zatem lambdy zachowują się jak obiekty funkcyjne, z tym wyjątkiem, że nie można uzyskać dostępu do klasy, która została wygenerowana w celu zaimplementowania lambda w jakikolwiek inny sposób niż użycie lambda. W związku z tym każda funkcja, która akceptuje funktory jako argumenty (zasadniczo oznacza dowolną funkcję inną niż C w bibliotece standardowej), zaakceptuje lambdas, ale żadna funkcja akceptująca tylko wskaźniki funkcji nie.
źródło
std::sort
na przykład), można zamiast tego korzystać z funkcji anonimowych. Jednak podczas definiowania funkcji, która powinna przyjmować funkcję anonimową jako argument, musisz użyć szablonu lub użyć jejstd::function
jako typu argumentu.+1
ode mnie.Zasadniczo funkcje lambda to funkcje tworzone „w locie”. W C ++ 1x można je wykorzystać do poprawy obsługi programowania funkcjonalnego:
Z grubsza spowoduje to kod podobny do tego:
Jeśli potrzebujesz
some_functor
tylko jednego wywołaniastd::for_each()
, funkcja lambda ma kilka zalet:źródło
Funkcja lambda to inna nazwa funkcji anonimowej - zasadniczo funkcja bez nazwy.
Zwykle używasz tego w językach, w których wystarczy użyć tej funkcji tylko raz. Na przykład zamiast
a następnie przekazanie tej funkcji do innej takiej funkcji
Z lambda po prostu byś to zrobił
źródło