Iteratory, Alokatory, Przyszlosc C++, Boost
Transkrypt
Iteratory, Alokatory, Przyszlosc C++, Boost
Iteratory, Alokatory, Przyszłość C++, Boost Biblioteka STL Sebastian Deorowicz Politechnika Śląska 2006–11–13 Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 1 / 50 Plan wykładu 1 Iteratory 2 Alokatory 3 Przyszłość C++ 4 Biblioteki Boost Wyrażenia lambda Przydatne narzędzia Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 2 / 50 Plan wykładu 1 Iteratory 2 Alokatory 3 Przyszłość C++ 4 Biblioteki Boost Wyrażenia lambda Przydatne narzędzia Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 3 / 50 Iteratory Cechy iteratorów W niektórych zastosowaniach istotne jest aby dysponując typem iteratora można się było dowiedzieć, np. o tym jaki jest typ elementów przez niego wskazywany Można te i inne informacje uzyskać dzięki tzw. cechom iteratorów Dla każdego typu iteratora Iterator (różnego od iteratora wyjściowego, dla którego jest nieco inaczej) są zdefiniowane następujące typy: iterator_traits<Iterator>::difference_type — typ różnicy iterator_traits<Iterator>::value_type — typ wskazywanej wartości iterator_traits<Iterator>::iterator_category — kategoria iteratora iterator_traits<Iterator>::reference — typ referencji do wskazywanego obiektu iterator_traits<Iterator>::pointer — typ wskaźnika do wskazywanego obiektu Dzięki tym cechom możliwe jest np. pisanie przeciążonych funkcji dla iteratorów różnego typu — przykładem może być standardowa funkcja distance, która jest różnie konkretyzowana w zależności od typu iteratora Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 4 / 50 Iteratory Własne iteratory Każda klasa iteratora musi mieć zdefiniowane cechy iteratora Cechy te podaje się konkretyzując klasę iterator, po której dziedziczy tworzona klasa iteratora Kiedy i jaki tworzyć iterator? Iteratory najczęściej tworzy się do nowych kolekcji, bo kolekcje istniejące są całkiem dobrze wyposażone w iteratory Może jednak być tak, że mamy jakieś specjalne wymagania i wtedy nawet dla standardowych kolekcji warto stworzyć iterator Jako przykład pokażemy sposób tworzenia iteratora wstawiającego na drugiej pozycji od początku Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 5 / 50 Iteratory — iterator wstawiający na drugiej pozycji (cz. 1) Przykład #include <algorithm> #include <vector> #include <iterator> using namespace std; template<class Collection> class insert_2nd_iterator : public iterator<output_iterator_tag, void, void, void, void> { protected: Collection& coll; public: typedef Collection container_type; explicit insert_2nd_iterator(Collection &c) : coll(c) {} insert_2nd_iterator<Collection>& operator=(const typename Collection::value_type& val) { if(coll.begin() == coll.end()) coll.insert(coll.begin(), val); else coll.insert(++coll.begin(), val); return *this; } insert_2nd_iterator<Collection>& operator*() { return *this; } insert_2nd_iterator<Collection>& operator++() { return *this; } insert_2nd_iterator<Collection>& operator++(int) { return *this; } }; Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 6 / 50 Iteratory — iterator wstawiający na drugiej pozycji (cz. 2) Przykład int _tmain(int argc, _TCHAR* argv[]) { int tab[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; vector<int> vi, vi2(tab, tab+10); insert_2nd_iterator<vector<int> > ivi(vi); copy(vi2.begin(), vi2.end(), ivi); ShowCollection(vi); // 0 9 8 7 6 5 4 3 2 1 } Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 7 / 50 Iteratory Co jeszcze? Tworzenie własnych iteratorów zostało przedstawione dość pobieżnie Więcej informacji dotyczących tworzenia własnych iteratorów: B. Stroustrup, Język C++, WNT, Warszawa, 2000 N. Josuttis, C++. Biblioteka standardowa. Podręcznik programisty, Helion, 2003 Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 8 / 50 Plan wykładu 1 Iteratory 2 Alokatory 3 Przyszłość C++ 4 Biblioteki Boost Wyrażenia lambda Przydatne narzędzia Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 9 / 50 Alokatory Po co wiedzieć coś więcej o alokatorach? Tworząc własną kolekcję możemy chcieć zapewnić interfejs zgodny z interfejsem kolekcji STL — one używają alokatorów do przydziału pamięci Może nam nie odpowiadać działanie domyślnego alokatora i będziemy chcieli stworzyć własny Czym są alokatory? Alokatory to abstrakcja — wszystko co zachowuje się jak alokator (udostępnia te same metody) jest alokatorem Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 10 / 50 Alokatory Metody udostępniane przez alokatory address(ref) — zwraca adres obiektu przekazanego przez referencję allocate(size) — alokuje obszar na size elementów deallocate(ptr, size) — zwalnia obszar pamięci wskazywany przez ptr i zajmowany przez size elementów construct(ptr, val) — konstruuje obiekt pod adresem ptr inicjalizując go wartością val destroy(ptr) — wywołuje destruktor dla obiektu wskazywanego przez ptr Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 11 / 50 Alokatory Co trzeba wiedzieć chcąc zdefiniować własny alokator? Dlaczego nie podoba się nam domyślny alokator Jak chcemy stworzyć lepszy i czy na pewno będzie się on lepiej sprawował Źródła wiedzy B. Stroustrup, Język C++, WNT, Warszawa, 2000 N. Josuttis, C++. Biblioteka standardowa. Podręcznik programisty, Helion, 2003 Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 12 / 50 Alokatory Przykładowy pomysł na nowy alokator Często domyślny alokator jest tak implementowany, że za każdym razem kiedy potrzebna jest pamięć, wywołuje operator new Nie ma to większego znaczenia dla kolekcji vector czy deque Dla kolekcji asocjacyjnych i list może to mieć jednak bardzo duże znaczenie Operator new rzadko kiedy jest bardzo efektywny, bo musi się komunikować z systemem operacyjnym Rozwiązaniem mogłoby być np. swego rodzaju „buforowanie” alokacji: alokator alokuje co jakiś czas większą pulę pamięci i na żądanie udostępnia właśnie ją dopiero po wyczerpaniu puli żąda od systemu operacyjnego nowego obszaru pamięci przy zwalnianiu małych obiektów, pamięć przez nie zajmowana trafia do puli i dopiero jeśli jest jej dużo, to zwalnia ją w systemie operacyjnym Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 13 / 50 Plan wykładu 1 Iteratory 2 Alokatory 3 Przyszłość C++ 4 Biblioteki Boost Wyrażenia lambda Przydatne narzędzia Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 14 / 50 Nieco dłuższa historia standaryzacji C++1 1985 — pierwsze wydanie książki B. Stroustrupa, Język C++ 1991 — pierwsze spotkanie komitetu standaryzacyjnego WG21 1994 — pierwsza robocza wersja standardu 1996 — druga robocza wersja standardu 1998 — standard C++98 2003 — pierwszy raport techniczny (TR1) 2004 — raport techniczny dotyczący wydajności (Performance TR) 2005 — dokument Library TR1 określający m.in. rozszerzenia biblioteki standardowej o kolekcje oparte na tablicach mieszających (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf) 2006(7) — dokument Decimal TR zawierający rozszerzenie języka o typy w arytmetyce dziesiętnej, decimal32, decimal64, decimal128 (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1977.html) 2007(8) — dokument Library TR2 zawierający kolejne rozszerzenia biblioteki standardowej, np. prawdopodobnie filesystem z Boost; można też zgłaszać własne propozycje :-) ok. 2010 — nowy standard C++0x 1 Na podstawie http://www.vollmann.ch/en/presentations/cpp-std-041.html Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 15 / 50 Library TR1 Nowe rzeczy Przestrzeń nazw std::tr1 Narzędzia ogólnego przeznaczenia Inteligentne wskaźniki shared ptr — na podstawie Boost Wyrażenia regularne — na podstawie Boost Generatory liczb pseudolosowych — na podstawie Boost Narzędzia wspomagające metaprogramowanie za pomocą wzorców: ang. reference wrapper Złączenia lambda Cechy typów (ang. type traits) Krotki (ang. tuples) Kolekcje Tablice stałych rozmiarów o interfejsie kolekcji — na podstawie Boost Kolekcje oparte na tablicach mieszających Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 16 / 50 Library TR1 Istniejące implementacje Na razie tylko Dinkumware (http://www.dinkumware.com/): wersja dla VC++ Express Edition — cena: $80 wersja dla VC++6 – VC++2005, GCC pod Linuxa (3.0 — 4.1.1) — cena: $200 wersja z kodami źródłowymi — cena: „tylko” $2300 Więcej szczegółów Ostatnia wersja robocza Library TR1 — http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf Dokumentacja Dinkumware — http://www.dinkumware.com/ Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 17 / 50 Kierunki rozwoju C++2 Plany — różnie może jeszcze być z ich realizacją Zachowanie wstecznej kompatybilności z C++ i C przy jednoczesnym rozwoju Rozwój narzędzi do programowania generycznego i niskopoziomowego Ułatwienie startu początkującym, m.in. poprzez garbage collection Rozszerzenia języka Wbudowanie Library TR1 do standardu i rozszerzenie go jeszcze o kolejne biblioteki 2 Na podstawie http://www.vollmann.ch/en/presentations/cpp-std-041.html Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 18 / 50 Kierunki rozwoju C++ Wybrane artykuły o C++0x B. Stroustrup, A Brief Look at C++0x, 2006, http://www.artima.com/cppsource/cpp0x.html G. Reis, B. Stroustrup, Specifying C++ Concepts, 2006, http://www.research.att.com/˜bs/popl06.pdf B. Stroustrup, The Design of C++0x, 2005, http://www.research.att.com/˜bs/rules.pdf Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 19 / 50 Plan wykładu 1 Iteratory 2 Alokatory 3 Przyszłość C++ 4 Biblioteki Boost Wyrażenia lambda Przydatne narzędzia Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 20 / 50 Biblioteki Boost Czym są? Stanowią rozszerzenie biblioteki standardowej C++ Część z nich została umieszczona w Library TR1, a inne kandydują do Library TR2 W wielu sytuacjach znacząco upraszczają kod Są oferowane na całkowicie darmowej licencji — jeszcze większa swoboda używania kodu niż dla GNU GPL Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 21 / 50 Biblioteki Boost — przegląd Przetwarzanie tekstów3 conversion/lexical cast — konwersje leksykalne (np. między typem string a typami liczbowymi) format — operacje podobne do printf, ale bezpieczne pod względem typów iostreams — strumienie wejścia/wyjścia z możliwością definiowania filtrów regex — wyrażenia regularne spirit — narzędzia do tworzenia analizatorów składniowych; zapis gramatyki podobny do notacji EBNF string algo — algorytmy tekstowe uzupełniające algorytmy obecne w bibliotece standardowej tokenizer — przetwarzanie tekstów podzielonych na tokeny wave — preprocesor funkcjonalnie zgodny preprocesorem C/C++ 3 Na podstawie http://www.boost.org Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 22 / 50 Biblioteki Boost — przegląd Kolekcje array — tablice o stałym rozmiarze; interfejs zgodny z STL, zwykle wydajniejsze niż vector dynamic bitset — alternatywa dla std::bitset umożliwiająca zmiany rozmiaru (zwykle wolniejsza) graph — grafy (z wieloma algorytmami na nich operującymi) multi array — tablice wielowymiarowe multi index — umożliwia indeksowanie kolekcji (w tym standardowych) według różnych kryteriów pointer container — kolekcje umożliwiające bezpieczne i wygodne przechowywanie wskaźników property map — definiuje interfejsy łączące obiekty klucze z obiektami wartości variant — kolekcja będąca uogólnieniem union Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 23 / 50 Biblioteki Boost – przegląd Iteratory graph — iteratory służące do nawigowania po grafach iterators — środowisko do wygodnego tworzenia iteratorów operators — wzorce ułatwiające definiowanie operatorów i iteratorów do własnych klas tokenizer — nawigacja po tekstach przetwarzanych jako tokeny Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 24 / 50 Biblioteki Boost — przegląd Algorytmy graph — algorytmy grafowe (np. Dijkstra) minmax — jednoczesne wyszukiwanie minimum i maksimum string algo — algorytmy przetwarzania tekstów utility — różne przydatne narzędzia, które gdzie indziej nie pasowały range — operacje na zakresach Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 25 / 50 Biblioteki Boost — przegląd Obiekty funkcyjne i programowanie wyższego rzędu bind, mem fn — uogólnienie bind1st, bind2nd funciton — mechanizm wywołań zwrotnych functional — rozszerzony zestaw adaptatorów obiektów funkcyjnych z STL functional/hash — haszujące obiekty funkcyjne lambda — nienazwane obiekty funkcyjne ref — przekazywanie referencji do obiektów do standardowych funkcji (eliminuje kosztowne kopiowanie) signals — implementacja sygnałów result of — wyznaczanie typu wyrażenia Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 26 / 50 Biblioteki Boost — przegląd Programowanie generyczne call traits — automatyczne wyznaczanie najlepszego sposobu przekazywania parametrów concept check — szablony ułatwiające programowanie generyczne enable if — sterowanie włączaniem do zbioru specjalizacji branych pod uwagę przy wywołaniach przeciążonych in place factory, typed in place factory — infrastruktura bezpośredniej konstrukcji obiektów zawieranych operators — ułatwienie wyposażania klas w operatory property map — definiuje interfejsy łączące obiekty klucze z obiektami wartości static assert — asercje czasu kompilacji type traits — informacje o typach w czasie kompilacji Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 27 / 50 Biblioteki Boost — przegląd Metaprogramowanie mpl — metaprogramowanie static assert — asercje czasu kompilacji type traits — informacje o typach w czasie kompilacji Metaprogramowanie preprocesora preprocessor — programowanie w preprocesorze z użyciem m.in. list, algorytmów, rekursji Programowanie współbieżne thread — przenośne programowanie wielowątkowe Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 28 / 50 Biblioteki Boost — przegląd Metaprogramowanie mpl — metaprogramowanie static assert — asercje czasu kompilacji type traits — informacje o typach w czasie kompilacji Metaprogramowanie preprocesora preprocessor — programowanie w preprocesorze z użyciem m.in. list, algorytmów, rekursji Programowanie współbieżne thread — przenośne programowanie wielowątkowe Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 28 / 50 Biblioteki Boost — przegląd Metaprogramowanie mpl — metaprogramowanie static assert — asercje czasu kompilacji type traits — informacje o typach w czasie kompilacji Metaprogramowanie preprocesora preprocessor — programowanie w preprocesorze z użyciem m.in. list, algorytmów, rekursji Programowanie współbieżne thread — przenośne programowanie wielowątkowe Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 28 / 50 Biblioteki Boost — przegląd Matematyka math — różne szablony i funkcje matematyczne numeric/conversion — bezpieczne konwersje pomiędzy typami numerycznymi integer — wydajne obliczenia na liczbach całkowitych interval — rozszerzenie obliczeń matematycznych na przedziały math/common factor — wyznaczanie NWD i NWW math/octonion – oktoniony (uogólnienie liczb zespolonych) math/quaternion — kwaterniony (uogólnienie liczb zespolonych) math/special functions — funkcje matematyczne takie jak np. atanh multi array — tablice wielowymiarowe operators — ułatwienie wyposażania klas w operatory random — generatory liczb pseudolosowych rational — obsługa liczb wymiernych uBLAS — algebra liniowa na wektorach i macierzach Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 29 / 50 Biblioteki Boost — przegląd Poprawność i testowanie concept check — szablony ułatwiające programowanie generyczne static assert — asercje czasu kompilacji test — narzędzia ułatwiające testowanie aplikacji Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 30 / 50 Biblioteki Boost — przegląd Struktury danych any — kolekcja umożliwiająca przechowywanie danych różnych typów compressed pair — uogólnienie std::pair wydajniej przechowujące pary, w których jeden z argumentów jest pusty multi index — umożliwia indeksowanie kolekcji (w tym standardowych) według różnych kryteriów pointer container — kolekcje umożliwiające bezpieczne i wygodne przechowywanie wskaźników typle — krotki (uogólnienie std::pair) variant — kolekcja będąca uogólnieniem union Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 31 / 50 Biblioteki Boost — przegląd Wejście/wyjście assign — wygodne przypisywanie szeregu wartości do kolekcji format — operacje podobne do printf, ale bezpieczne pod względem typów io state savers — zachowanie stanu obiektów biblioteki iostream iostreams — strumienie wejścia/wyjścia z możliwością definiowania filtrów program options — wygodne przetwarzanie parametrów wywołania programu z wiersza poleceń lub parametrów z plików konfiguracyjnych serialization — serializacja (zachowywanie i przywracanie stanu) obiektów Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 32 / 50 Biblioteki Boost — przegląd Inne języki programowania python — współpraca programów w C++ i Pythonie Pamięć operacyjna pool — obsługa pul pamięciowych (pojedyncze alokacje na dużą liczbę małych obiektów) smart ptr — różnego rodzaju „inteligentne” wskaźniki utility — różne przydatne narzędzia, które gdzie indziej nie pasowały Parsowanie spirit — narzędzia do tworzenia parserów Interfejsy programistyczne function — mechanizm wywołań zwrotnych parameter — przekazywanie nazwanych parametrów Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 33 / 50 Biblioteki Boost — przegląd Inne języki programowania python — współpraca programów w C++ i Pythonie Pamięć operacyjna pool — obsługa pul pamięciowych (pojedyncze alokacje na dużą liczbę małych obiektów) smart ptr — różnego rodzaju „inteligentne” wskaźniki utility — różne przydatne narzędzia, które gdzie indziej nie pasowały Parsowanie spirit — narzędzia do tworzenia parserów Interfejsy programistyczne function — mechanizm wywołań zwrotnych parameter — przekazywanie nazwanych parametrów Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 33 / 50 Biblioteki Boost — przegląd Inne języki programowania python — współpraca programów w C++ i Pythonie Pamięć operacyjna pool — obsługa pul pamięciowych (pojedyncze alokacje na dużą liczbę małych obiektów) smart ptr — różnego rodzaju „inteligentne” wskaźniki utility — różne przydatne narzędzia, które gdzie indziej nie pasowały Parsowanie spirit — narzędzia do tworzenia parserów Interfejsy programistyczne function — mechanizm wywołań zwrotnych parameter — przekazywanie nazwanych parametrów Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 33 / 50 Biblioteki Boost — przegląd Inne języki programowania python — współpraca programów w C++ i Pythonie Pamięć operacyjna pool — obsługa pul pamięciowych (pojedyncze alokacje na dużą liczbę małych obiektów) smart ptr — różnego rodzaju „inteligentne” wskaźniki utility — różne przydatne narzędzia, które gdzie indziej nie pasowały Parsowanie spirit — narzędzia do tworzenia parserów Interfejsy programistyczne function — mechanizm wywołań zwrotnych parameter — przekazywanie nazwanych parametrów Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 33 / 50 Biblioteki Boost — przegląd Różne conversion — rzutowania polimorficzne i leksykalne numeric/conversion — konwersje numeryczne crc — obliczanie sum kontrolnych date time — operacje na datach filesystem — przenośne operacje na katalogach, plikach, ścieżkach dostępu optional — wzorzec uzupełniający typ o wartość specjalną (np. informacje o błędzie) program options — wygodne przetwarzanie parametrów wywołania programu z wiersza poleceń timer — przenośny pomiar czasu tribool — 3-wartościowy typ logiczny utility — różne przydatne narzędzia, które gdzie indziej nie pasowały value initialized — unifikacja sposobu inicjalizacji obiektów Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 34 / 50 Boost/Lambda Czym jest biblioteka lambda?4 Wyrażenia lambda to inaczej funkcje nienazwane Wyrażenia te przydają się np. wtedy, kiedy mamy do napisania mały obiekt funkcyjny, który zostanie użyty tylko raz i szkoda nam miejsca/czasu na definiowanie obiektu 4 Dostępna w pliku nagłówkowym boost/lambda/lambda.hpp i kilku innych Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 35 / 50 Boost/Lambda — zobaczmy jak to wygląda Przykład #include #include #include #include #include "stdafx.h" <iostream> <vector> <algorithm> <boost/lambda/lambda.hpp> using namespace boost::lambda; int _tmain(int argc, _TCHAR* argv[]) { int tab[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; std::vector<int> vi(tab, tab+10); for_each(vi.begin(), vi.end(), std::cout << _1*2 << "\n"); } Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 36 / 50 Boost/Lambda Wyrażenia lambda Symbole zastępcze 1, . . . , 9 są cechą charakterystyczną wyrażeń lambda — przechowują argumenty Nazwy tych symboli można w razie potrzeby przedefiniować Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 37 / 50 Boost/Lambda Przykład #include #include #include #include "stdafx.h" <iostream> <boost/lambda/lambda.hpp> <boost/function.hpp> using namespace boost::lambda; int _tmain(int argc, _TCHAR* argv[]) { (std::cout << _4 << " " << _3 << " " << _2 << " " << _1 << "\n") ("Co", "to", "jest", "lambda"); // lambda to jest Co boost::function<double(double, double, double)> delta = _2*_2 - 4*_1*_3; std::cout << delta(2, 3, 5); // -31 } Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 38 / 50 Boost/Lambda Kilka instrukcji w wyrażeniu Wewnątrz wyrażenia nie wolno użyć średnika, ale można przecinka — jako separatora Trzeba pamiętać, aby całość ująć w nawiasy Przykład int tab[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; vector<int> vi(tab, tab+10); for_each(vi.begin(), vi.end(), (_1 *= 2, cout << _1 << " ")); // 0 2 4 6 8 10 12 14 16 18 Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 39 / 50 Boost/Lambda Wywoływanie funkcji w wyrażeniach lambda Biblioteka oferuje wzorzec bind służący do wiązania wywołań z parametrami5 Wzorzec znacznie wygodniejszy w użyciu niż standardowe bind1st Przykład double power(double x, int n) { double r; for(r = 1; n > 0; n--) r *= x; return r; } ... int tab[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; vector<int> vi(tab, tab+10); for_each(vi.begin(), vi.end(), cout << bind(&power, _1, 3) << " "); // 0 1 8 27 64 125 216 343 512 729 5 W pliku nagłówkowym boost/lambda/bind.hpp Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 40 / 50 Boost/Lambda Przykład int tab[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; vector<int> vi(tab, tab+10); for_each(vi.begin(), vi.end(), cout << _1 << " "); cout << endl; for_each(vi.begin(), vi.end(), cout << " " << _1); cout << endl; for_each(vi.begin(), vi.end(), cout << constant(" ") << _1); cout << endl; // 0 1 2 3 4 5 6 7 8 9 // 0123456789 // 0 1 2 3 4 5 6 7 8 9 Uwaga na to co jest wyrażeniem lambda W drugim przykładzie wynik cout << " " nie jest wyrażeniem lambda więc tylko raz będzie ten kod wykonany Dopiero pojawienie się _1 sygnalizuje, że mamy do czynienia z wyrażeniem lambda Trzeba jawnie zapisać, że chodzi o wyrażenie lambda (constant) Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 41 / 50 Boost/Lambda Przykład int tab[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; vector<int> vi(tab, tab+10); for_each(vi.begin(), vi.end(), cout << _1 << " "); cout << endl; for_each(vi.begin(), vi.end(), cout << " " << _1); cout << endl; for_each(vi.begin(), vi.end(), cout << constant(" ") << _1); cout << endl; // 0 1 2 3 4 5 6 7 8 9 // 0123456789 // 0 1 2 3 4 5 6 7 8 9 Uwaga na to co jest wyrażeniem lambda W drugim przykładzie wynik cout << " " nie jest wyrażeniem lambda więc tylko raz będzie ten kod wykonany Dopiero pojawienie się _1 sygnalizuje, że mamy do czynienia z wyrażeniem lambda Trzeba jawnie zapisać, że chodzi o wyrażenie lambda (constant) Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 41 / 50 Boost/Lambda Przykład int tab[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; vector<int> vi(tab, tab+10); int i = 0; for_each(vi.begin(), vi.end(), cout << "vi[" << i++ << "]=" << _1 << " "); cout << endl; // vi[0]=0 1 2 3 4 5 6 7 8 9 for_each(vi.begin(), vi.end(), cout << constant("vi[") << var(i)++ << "]=" << _1 << " "); cout << endl; // vi[1]=0 vi[2]=1 vi[3]=2 vi[4]=3 vi[5]=4 vi[6]=5 vi[7]=6 vi[8]=7 vi[9]=8 vi[10]=9 Uwaga na zmienne Ze zmiennymi jest analogicznie jak ze stałymi Jeśli chcemy używać zmiennej, to musimy ją ująć w var() Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 42 / 50 Boost/Lambda Przykład int tab[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; vector<int> vi(tab, tab+10); int i = 0; for_each(vi.begin(), vi.end(), cout << "vi[" << i++ << "]=" << _1 << " "); cout << endl; // vi[0]=0 1 2 3 4 5 6 7 8 9 for_each(vi.begin(), vi.end(), cout << constant("vi[") << var(i)++ << "]=" << _1 << " "); cout << endl; // vi[1]=0 vi[2]=1 vi[3]=2 vi[4]=3 vi[5]=4 vi[6]=5 vi[7]=6 vi[8]=7 vi[9]=8 vi[10]=9 Uwaga na zmienne Ze zmiennymi jest analogicznie jak ze stałymi Jeśli chcemy używać zmiennej, to musimy ją ująć w var() Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 42 / 50 Boost/Lambda Instrukcje sterujące6 if_then(cond, then_code), if_(cond)[then_code] — alternatywne postacie instrukcji warunkowej if_then_else(cond, then_code, else_code), if_(cond)[then_code].else_[else_code] — znowu instrukcje warunkowe while_loop(cond, body), while_(cond)[body] — alternatywne postacie instrukcji pętli while while_loop(cond) — pętla while bez ciała do_while_loop(cond, body), do_[body].while_(cond) — alternatywne postacie instrukcji pętli do while do_while_loop(cond) — pętla do while bez ciała for_loop(init, cond, incr, body), for_(init, cond, incr)[body] — instrukcja pętli for for_loop(init, cond, incr) — instrukcja pętli for bez ciała if_then_else_return(cond, then_code, else_code) — operator ?: 6 Dostępne w plikach nagłówkowych boost/lambda/if.hpp oraz boost/lambda/loops.hpp Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 43 / 50 Boost/Lambda Przykład #include "stdafx.h" #include <algorithm> #include <iostream> #include <vector> #include <boost/lambda/lambda.hpp> #include <boost/lambda/if.hpp> #include <boost/lambda/loops.hpp> using namespace std; using namespace boost::lambda; int _tmain(int argc, _TCHAR* argv[]) { int tab[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; vector<int> vi(tab, tab+10); random_shuffle(vi.begin(), vi.end()); for_each(vi.begin(), vi.end(), if_(_1 < 5)[cout << _1 << " "].else_[cout << -_1 << " "]); cout << endl; // -8 1 -9 2 0 -5 -7 3 4 -6 for_each(vi.begin(), vi.end(), for_(var(cout) << "\n", _1 > 0, _1--)[var(cout) << "*"]); // ******** // * // ********* // ** // ... } Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 44 / 50 Boost/Lambda Podsumowanie Wyrażenia lambda pozwalają na znacznie więcej niż tu pokazano — przykłady miały raczej zachęcić do poznania biblioteki niż ją w całości zaprezentować Wyrażenia lambda są pomocne szczególnie wtedy, kiedy normalnie utworzono by niewielki obiekt funkcyjny Dokładniejsze omówienie tych wyrażeń: B. Karlsson, Więcej niż C++. Wprowadzenie do bibliotek Boost, Helion, 2006 http://www.boost.org/doc/html/lambda.html Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 45 / 50 Boost/static assert Asercje w C++ W C++ dostępne są asercje obliczane w czasie działania programu (assert) — powodują one zatrzymanie wykonywania programu w przypadku wystąpienia błędu krytycznego, który uniemożliwia dalsze działanie programu Asercje w C++ z Boost Biblioteka static assert udostępnia makrodefinicję BOOST_STATIC_ASSERT obliczaną w czasie kompilacji — zatrzymuje ona kompilację z komunikatem o błędzie Kiedy asercje czasu kompilacji mają sens? Kiedy nie ma sensu kompilować programu, bo programista popełnił błąd przy stosowaniu biblioteki czy własnych funkcji W metaprogramowaniu, które staje się obecnie coraz popularniejsze Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 46 / 50 Boost/static assert Przykład #include "stdafx.h" #include <boost/static_assert.hpp> using namespace boost; // Tylko 64-bitowy kompilator BOOST_STATIC_ASSERT(sizeof(int) == 8); int _tmain(int argc, _TCHAR* argv[]) { ... } Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 47 / 50 Boost/Any Opis Biblioteka udostępnia klasę any zdolną do przechowywania wartości w zasadzie dowolnego typu Dostępny jest też wzorzec funkcji any cast służącej do „wyciągania” wartości odpowiedniego typu Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 48 / 50 Boost/Any Przykład #include "stdafx.h" #include <algorithm> #include <vector> #include <bitset> #include <iostream> #include <boost/any.hpp> using namespace std; using namespace boost; bool check_string(const any& X) { return any_cast<string>(&X) != NULL; } int _tmain(int argc, _TCHAR* argv[]) { vector<any> va; int i = 10; double d = 20.53; string s = "Tekst"; bitset<10> b(string("100001110")); va.push_back(i); va.push_back(s); va.push_back(d); va.push_back(b); va.push_back(s); cout << count_if(va.begin(), va.end(), check_string) << endl; cout << any_cast<int>(va[0]) << endl; cout << any_cast<string>(va[2]) << endl; // 2 // 10 // Tekst } Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 49 / 50 Co będzie za tydzień? Poznamy kolejne możliwości bibliotek Boost, m.in., wyrażenia regularne, grafy Dowiemy się o tym jakie są jeszcze inne przydatne i popularne biblioteki Poznamy ideę metaprogramowania Sebastian Deorowicz (PŚl) Iteratory, Alokatory, Przyszłość C++, Boost 2006–11–13 50 / 50