przejście do zawartości
zpr c++ quick reference
Narzędzia użytkownika
Zarejestruj się!
Zaloguj
Narzędzia witryny
Narzędzia
Pokaż stronę
Poprzednie wersje
Odnośniki
Ostatnie zmiany
Menadżer multimediów
Indeks
Zaloguj
Zarejestruj się!
Ostatnie zmiany
Menadżer multimediów
Indeks
Ślad:
lambda
Ta strona jest tylko do odczytu. Możesz wyświetlić źródła tej strony ale nie możesz ich zmienić.
====== Biblioteka Boost Lambda ====== Biblioteka standardowa 'algorithm' udostępnia wiele przydatnych szablonów umożliwiających wykonywanie często potrzebnych algorytmów na kontenerach. Konstrukcje te umożliwiają np. wyszukiwanie, sortowanie, przeglądanie z modyfikacją itp. Problem w tym, że dla każdej operacji trzeba było implementować drobną klasę tzw.obiekt funkcyjny. Obiekt ten miał za zadanie dostarczyć odpowiedniego operatora czy funkcji która miała za zadanie określić logikę operacji na elementach kontenera. Następnie obiekt był przekazywany do szablonu. Taka metoda powodowała powstanie wiele obiektów funkcyjnych które niekiedy w dużym projekcie były wykorzystywane tylko raz. Biblioteka boost wprowadza mechanizm (wraz z mechanizmami pomocniczymi) który umożliwia konstruowanie tak zwanych wyrażeń lambda. Można je rozumieć jako nienazwane funkcje które są wykonywane w miejscu definicji. ===== Zalety ===== Biblioteka boost charakteryzuje się następującymi zaletami: * mniejsza ilość kodu. * skupienie kodu w miejscu faktycznego wykorzystania. * łatwość konserwacji kodu (nie trzeba badać szeregu obiektów funkcyjnych) * zmniejszenie zapotrzebowania pamięci przez program. ===== Wady ===== Biblioteka boost charakteryzuje się następującymi wadami: * trudna i z początku ni jak nie intuicyjna składnia. * drobna pomyłka programisty to szereg błędów i ostrzeżeń generowanych przez kompilator (efekt zaawansowanych mocno zagłębionych szablonów). * zbyt "fachowe" podejście do tworzenia wyrażeń może znacznie utrudnić zrozumienie kodu przez innych programistów. ===== Przykłady ===== Poniższe przykłady pokazują (w niewielkim stopniu) możliwości tych wyrażeń. Należy w tym miejscu zwrócić uwagę, że często wyrażenia lambda wykorzystują mechanizmy pomocnicze zdefiniowane w innych bibliotekach których nagłówki należy dołączyć. Standardowo dołączamy bibliotekę boost\lambda\lambda.hpp. W przykładach będą pokazane nagłówki które dodatkowo należy dołączyć by kod się skompilował. ==== Pierwszy rzut oka na boost::lambda ==== W wyrażeniach lambda argumenty oznaczamy jako _X gdzie X może być cyfrą od 1 do 9. Bibloteka boost umożliwia zmianę nazwy _X na dowolną poprzez użycię boost::lambda::placeholderX_type. Jednak nie zaleca sie tego robić ze względu na możliwość skonfudowania programistów uczestniczących w projekcie, a przyzwyczajonych do standardowego oznaczenia. <code cpp> #include <boost/lambda/lambda.hpp> using namespace boost::lambda; (std::cout << _2 << " " << _1 << " " << _3 << "\n") // Definicja wyrażenia ("zadna lala,","Zadna panna,", "nie zastapi terminala!\n"); // Argumenty wywołania. </code> Kod ten możemy odczytać jako: Wywołaj w tym konkretnym miejscu funkcję którą wyprowadzi na standardowe wyjście argumenty w kolejności 2,1,3. ==== Elementy kontenerów ==== Jednym z głównych powodów stworzenia boost::lambda było umożliwienie szybszego kodowania operacji na kontenerach. Załóżmy, że mamy kolekcje obiektów i chcemy na każdym z nich wykonać funkcję. Funkcja ta dodatkowo będzie wykonywana w programie tylko z argumentami pochodzącymi z tego kontenera i tylko w jednym miejscu. Załóżmy, że mamy: <code cpp> void funkcja_globalna (const float i) { std::cout << "\nvoid funkcja_globalna : " << i; } struct Example { void funkcja_klasy (const float i) const { std::cout << "\nvoid example::funkcja_klasy : " << i; } ~Example(){}; }; std::vector<float> vec_test; </code> Dawniej problem trzeba było rozwiązać tak: <code cpp> #include <algorithm> #include <functional> Example ex; Example * ex_ptr = &ex; std::cout << "Uzycie std::ptr_fun dla wiazania funkcji globalnej."; std::for_each(vec_test.begin(), vec_test.end(), std::ptr_fun(funkcja_globalna)); std::cout << "Wiazanie z metoda klasy za pomoca mem_fun_ref (dla obiektu ex)."; std::for_each(vec_test.begin(), vec_test.end(), std::bind1st(std::mem_fun_ref(&example::funkcja_klasy), ex)); std::cout << "Wiazanie z metoda klasy za pomoca mem_fun (dla wskazania do obiektu ex)."; std::for_each(vec_test.begin(), vec_test.end(), std::bind1st(std::mem_fun(&example::funkcja_klasy), ex_ptr)); </code> Przy używaniu metod z obecnego standardu musimy rozróżnić wiązania dla obiektów i dla wskazań na te obiekty. Wyrażenia boost::lambda oraz boost::bind "domyślają się" z czym mają do czynienia. Zatem powyższy kod możemy zastąpić nieco lepszym używającym boost:bind : <code cpp> #include <algorithm> #include <boost/lambda/lambda.hpp> #include <boost/lambda/bind.hpp> std::cout << "\n\nUzycie boost::bind dla funkcji globalnych."; std::for_each(vec_test.begin(), vec_test.end(), bind(&funkcja_globalna,_1)); std::cout << "\n\nUzycie boost::bind dla funkcji obiektow klasy."; std::for_each(vec_test.begin(), vec_test.end(), bind(&example::funkcja_klasy, ex ,_1)); std::cout << "\n\nUzycie boost::bind dla funkcji wskazan do obiektow klasy."; std::for_each(vec_test.begin(), vec_test.end(), bind(&example::funkcja_klasy, ex_ptr ,_1)); </code>
lambda.1208376058.txt.gz
· ostatnio zmienione: 2008/04/16 22:00 przez
przemo86
Narzędzia strony
Pokaż stronę
Poprzednie wersje
Odnośniki
Do góry