( rednio) zaawansowane programowanie w C++ (ZPR) Wykªad 11 - STL, bind Robert Nowak 2016Z ( rednio) zaawansowane programowanie w C++ (ZPR) 1/35
Programowanie generyczne - powtórzenie wspóªdzielenie kodu ¹ródªowego (, ) brak narzutów w czasie wykonania problemy: trudne w implementacji rozrost kodu wykonywalnego nieczytelne komunikaty o bª dach ( rednio) zaawansowane programowanie w C++ (ZPR) 2/35
Biblioteka STL (standardowa w C++ od 1997) Skªad: iteratory funktory (ob. funkcyjne) adaptery alokatory Cechy: wykorzystuje mechanizm szablonów kod wielokrotnego u»ycia mo»na stosowa do typów wbudowanych wykorzystuje wzorzec iteratora (zmniejsza liczb algorytmów) bezpieczna w aplikacjach wielow tkowych bardzo efektywna ( rednio) zaawansowane programowanie w C++ (ZPR) 3/35
Lista kolekcji standardowych basic_string vector list deque set map multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap sekwencyjne jednowymiarowa tablica jednowymiarowa tablica lista dwukierunkowa kolejka o dwu ko«cach asocjacyjne zbiór tablica asocjacyjna (sªownik) warto± mo»e wyst powa wielokrotnie klucz mo»e wyst powa wielokrotnie haszuj ce zbiór sªownik wielozbiór wielosªownik ( rednio) zaawansowane programowanie w C++ (ZPR) 4/35
Kontenery adaptery queue<t> kolejka priority_queue<t> kolejka priorytetowa stack<t> stos Inny podziaª: bazuj ce na tablicach: vector, string, deque bazuj ce na w zªach: list, set, map, multiset, multimap, unorderd_set, unorderd_map, unorderd_multiset, unorderd_multimap ( rednio) zaawansowane programowanie w C++ (ZPR) 5/35
Kopiowanie w bibliotece STL Biblioteka operuje na kopiach (kontener przechowuje kopie elementów) Obiekty przechowywane w kontenerach: powinny mie publiczny konstruktor kopiuj cy powinny mie publiczny operator przypisania Problemy: obiekty bazowe dla hierarchii klas (wycinanie) auto_ptr(t) (nietypowe kopiowanie) Gdy kopiowanie kosztowne: kontener wska¹ników na obiekty kontener sprytnych wska¹ników ze zliczaniem (shared_ptr) ( rednio) zaawansowane programowanie w C++ (ZPR) 6/35
std::vector Nagªówek: <vector> //Deklaracja template<class T, class A=allocator<T> > class std::vector; //Najwa»niejsze metody dost pu reference operator[](size_type n); reference at(size_type n) front() back() //Modyfikacja kolekcji void push_back(const&t); T pop_back(); //Wa»ne funkcje pomocnicze bool operator== bool operator< //Specjalizacje vector<bool> vector size capacity ptr 5 10 ( rednio) zaawansowane programowanie w C++ (ZPR) 7/35
std::list Nagªówek: <list> //Deklaracja template<class T, class A=allocator<T> > class std::list; //Metody dost pu - brak operatora[] front() back() //Modyfikacja kolekcji push_front(), push_back() pop_front(), pop_back() list head tail //Modyfikacja kolekcji insert erase //Inne metody void remove(const T& val) void reverse() splice merge sort ( rednio) zaawansowane programowanie w C++ (ZPR) 8/35
std::deque - kolejka o dwu ko«cach Nagªówek <deque> deque start end empty empty empty Operacje: takie jak dla wektora (za wyj tkiem capacity(), reserve() ) operacje z przodu ci gu (tak jak dla listy) ( rednio) zaawansowane programowanie w C++ (ZPR) 9/35
asocjacyjne ale: przechowuj elementy uporz dkowane dostarczaj metod wyszukiwania w czasie logarytmicznym Alternatywa: posortowany wektor porz dek elementów inny ni» kolejno± wstawiania iterator typu bidirectional, cz sto wymagaj random_access ( rednio) zaawansowane programowanie w C++ (ZPR) 10/35
set - zbiór eliminacja elementów równowa»nych a jest równowa»ne b, je»eli!(a < b) &&!(b < a) set<int> s; //zbiór liczb caªkowitych s.insert(1); //dodaje elementy do kolekcji s.insert(1); //ta operacja jest pusta (usuwa elementy równowa»ne) s.insert(2); assert( s.size() == 2); //bada liczb elementów assert( s.count(1) == 1 ); //zlicza liczb wyst pie«elementu ( rednio) zaawansowane programowanie w C++ (ZPR) 11/35
map - sªownik (tablica asocjacyjna) template<class K, class T, //typ klucza i warto±ci class Cmp = less<key>, //Porz dek dla klucza class A = allocator<pair<const K, T> > > class std::map; map key value iterator find(const K& k); size_type count(const K& k) const; pair<iter,iter> equal_range(const K& k); ( rednio) zaawansowane programowanie w C++ (ZPR) 12/35
boost::unordered_set lub std::unordered_set (C++11) nie zostaªy obj te standardem w 1999 roku dostawcy kompilatorów (wªasne rozwi zania): hash_set, hash_map, itd. standard C++11: unordered_set itd. wykorzystuj funkcj skrótu w przybli»eniu jednostkowy czas dost pu do elementów cena: zaj to± pami ci (dziaªa dobrze gdy wypeªniony w ok. 25%) ( rednio) zaawansowane programowanie w C++ (ZPR) 13/35
boost::array <boost/array.hpp> lub std::array (C++11) Adapter dla tablic z C dostarcza iteratorów oraz metod begin, end, rbegin, rend dostarcza metody: at, front, back i in. dostarcza operator==, operator< template<typename T, std::size_t N> class array { public: //... T elems[n]; }; //Przykªady u»ycia array<double, 4> tab = { 1.0, 1.1, 1.2, 1.3 }; array<double, 4> tab2(tab); cassert( tab == tab2 ); tab2.assign(0.0); //wszystkie elementy b d miaªy warto± 0 ( rednio) zaawansowane programowanie w C++ (ZPR) 14/35
Porównanie kolekcji - wydajno± indeksowanie insert, erase pocz tek koniec array O(1) - - - vector O(1) O(n)+ - O(1)+ list - O(1) O(1) O(1) deque O(1) O(n) O(1) O(1) set,map O(log(n)) O(log(n)) - - unordered O(1)+ O(1)+ - - array - tablica odziedziczona po 'C' wektor - dost p przez indeks, rezerwowanie pami ci lista - optymalne wstawianie i usuwanie elementów deque - optymalne operacje na ko«cach, indeksowanie ( rednio) zaawansowane programowanie w C++ (ZPR) 15/35
Porównanie kolekcji cecha element w ustalonej pozycji kontenera dost p przez indeks wa»na szybko± wyszukiwania iteratory, wska¹niki nie mog by uniewa»niane j.w. dla operacji modykuj cej koniec kolekcji brak elementów równowa»nych nieistotny porz dek w jakim elementy s przechowywane kontener vector, string, list, deque vector, string, deque posortowane wektory, asocjacyjne, haszuj ce lista, asocjacyjne j.w. oraz deque set, map haszuj ce ( rednio) zaawansowane programowanie w C++ (ZPR) 16/35
STL i wielow tkowo± bezpiecznie czytanie bezpieczne pisanie do ró»nych kontenerów wiele w tków mo»e równocze±nie czyta z kontenera ró»ne w tki mog równocze±nie pisa do ró»nych kontenerów //Uwaga: string cz sto implementowany jako proxy-on-write void f(string s) { s += 'a';//modyfikacja napisu } rozwa»y zast pienie string przez vector<char> dla bardzo starych wersji biblioteki standardowej ( rednio) zaawansowane programowanie w C++ (ZPR) 17/35
niemodykuj ce for_each nd nd_if adjacent_nd nd_rst_of count count_if mismatch equal search search_n nd_end modykuj ce copy copy_n copy_backward swap iter_swap swap_ranges transform replace replace_if replace_copy replace_copy_if ll ll_n generate generate_n remove remove_if remove_copy... sortuj ce, zbiorowe, sterta, i in. ( rednio) zaawansowane programowanie w C++ (ZPR) 18/35
zakres, reverse-iterator iterator begin(); iterator do pierwszego elementu iterator end(); iter. do pierwszego za ostatnim reverse_iterator rbegin(); iteratory dla odwrotnej kolejno±ci reverse_iterator rend(); begin end A B C D rbegin rend D C B A ( rednio) zaawansowane programowanie w C++ (ZPR) 19/35
wykorzystanie algorytmów int TAB[] = { 3, 2, 0, 9, 1 }; vector<int> v(tab, TAB + sizeof(tab)/sizeof(tab[0]) ); //Jawna p tla for(int i : v) { cout << i << ' '; } for(vector<int>::const_iterator ii = v.begin(); ii!= v.end(); ++ii ) { cout << *ii << ' '; } //Pomocniczy funktor struct PrintFunctor : public std::unary_function<x,void> { void operator()(int x) { cout << x << ' '; } }; //Algorytm: zwarty kod, nie wywoªuje wielokrotnie v.end() for_each( v.begin(), v.end(), PrintFunctor() ); //Inny algorytm copy( v.begin(), v.end(), ostream_iterator<int>(cout," ") ); ( rednio) zaawansowane programowanie w C++ (ZPR) 20/35
wyszukiwanie Maj c zakres: elementy nieposortowane count int czy istnieje element i ile kopii nd iterator czy istnieje element i gdzie si znajduje elementy posortowane binary_search bool czy istnieje element lower_bound iterator upper_bound iterator equal_range para iteratorów Maj c kontener: sekwencyjny: tak jak zakres (begin, end) asocjacyjny: wykorzysta metody kontenera ( rednio) zaawansowane programowanie w C++ (ZPR) 21/35
usuwanie (remove nie usuwa elementów) Iter remove(iter rst, Iter last, const T& val) //Przykªad usuwania elementów vector<int> v; v.erase( remove(v.begin(), v.end(), 3), v.end() ); remove niebezpieczne dla kontenerów zawieraj cych wska¹niki ( rednio) zaawansowane programowanie w C++ (ZPR) 22/35
sortowanie partition dzieli elementy u»ywaj c predykatu stable_partiton j.w. nth_element znajduje pozycj danego elementu partial_sort sortuje cz ±ciowo sort stable_sort sortuje sortuje, dla elementów równowa»nych zachowany porz dek ( rednio) zaawansowane programowanie w C++ (ZPR) 23/35
std::min, std::max z <algorithm> //wykorzystuje operator< template <class T> const T& min ( const T& a, const T& b ) { return!(b<a)?a:b; } //wªasny operator porównania template <class T, class Compare> const T& min ( const T& a, const T& b, Compare comp ) { return!comp(b,a)?a:b; } cout << min(2,1) << endl; //drukuje 1 //Ze wzgl du na to,»e windows.h definiuje makrodefinicje min i max //czasami nale»y u»y dodatkowej pary nawiasów cout << (std::min)(2,1) << endl; //dziaªa poprawnie na Windows //mo»na te» zdefiniowa makrodefinicj #define NOMINMAX //mo»na u»ywa szablonów _cpp_min _cpp_max ( rednio) zaawansowane programowanie w C++ (ZPR) 24/35
Boost Algorithm Minmax #include <boost/algorithm/minmax.hpp> #include <boost/algorithm/minmax_element.hpp> //znajduje minimalny element w kolekcji, zªo»ono± liniowa template <class It> It std::min_element(it first, It last); //znajduje maksymalny element w kolekcji, zªo»ono± liniowa template <class It> It std::max_element(it first, It last); template <class It> //zªo»ono± 3n/2 std::pair<it,it> boost::minmax_element(it first, It last); const int TAB[] = {3,7,2,5,6,4,9}; const int SIZE = sizeof(tab)/sizeof(tab[0]); cout << "min:" << *min_element(tab, TAB + SIZE) << endl; //zwraca uporz dkowan par template <class T> tuple<t const&, T const&> boost::minmax(const T& a, const T& b); ( rednio) zaawansowane programowanie w C++ (ZPR) 25/35
bind bind ( rednio) zaawansowane programowanie w C++ (ZPR) 26/35
bind std::bind lub boost::bind <boost/bind.hpp> <functional> zast puje: - ptr_fun - mem_fun - mem_fun1 - mem_fun_ref - mem_fun1_ref - bind1st - bind2nd - compose - compose2 //definiuje _1, _2, _3, itp using namespace std::placeholders; void f(int i, int j); //Przykªad - nowy obiekt funkcyjny void f2(int j) { return f(5,j) } bind1st(ptr_fun(f),5); //wykorzystuje STL std::bind(f, 5, _1);//to samo boost::bind(f, 5, _1);//wykorzystuje bind //Przykªad - funkcja z 4 argumentami void arg4(int i1, int i2, int i3, int i4) { cout << i1 << i2 << i3 << i4; } int i1=1, i2=2, i3=3, i4=4; //Tworzy obiekt funkcyjny i wykonuje go (bind( &arg4, _4, _2, _3, _1 )) (i1, i2, i3, i4); //Wykorzystuje tylko i3 (bind( &arg4, _3, _3, _3, _3 )) (i1, i2, i3, i4); ( rednio) zaawansowane programowanie w C++ (ZPR) 27/35
bind bind - przykªady class Foo { public: void print(); /*... */ }; void printfun(const Foo& f) { f.print(); } std::vector<foo> v; for_each(v.begin(), v.end(), printfun ); //Wykorzystuje funkcj for_each(v.begin(), v.end(), mem_fun_ref(&foo::print) ); for_each(v.begin(), v.end(), bind(&foo::print,_1) ); std::vector<foo*> v2; for_each(v2.begin(), v2.end(), mem_fun(&foo::print) ); for_each(v2.begin(), v2.end(), bind(&foo::print,_1) ); std::vector<shared_ptr<foo> > v3; for_each(v3.begin(), v3.end(), bind(&foo::print,_1) ); ( rednio) zaawansowane programowanie w C++ (ZPR) 28/35
bind std::ref (boost::ref) nagªówek <functional> lub <boost/ref.hpp> std::ref(x) obiekt zawieraj cy referencj do X, mo»liwo± kopiowania, itp. std::cref(x) obiekt zaw. staª referencj do X //Przykªady vector<int> v; struct X { void f(int i); }; X x; //Dziaªania wykonuje na kopii x for_each( v.begin(), v.end(), bind( &X::f, x, _1 ) ); //Dziaªania wykonuje na obiekcie x for_each( v.begin(), v.end(), bind( &X::f, ref(x), _1 ) ); ( rednio) zaawansowane programowanie w C++ (ZPR) 29/35
bind bind - przykªady (2) struct Point { //Klasa u»ywana w przykªadach Point(int x, int y) : x_(x), y_(y) {} int x_; int y_; void move(int dx, int dy) { x_ += dx; y_ += dy; } }; vector<int> vi; //tutaj pomini to dodawanie warto±ci do wektora Point p(0,0); //Przykªad wykorzystania algorytmu struct Fun1 { //Obiekt funkcyjny wykorzystywany w algorytmie Point& p_; Fun1(Point& p) : p_(p) {} void operator()(int i) { p_.move(i, i); } } fun1(p); for_each(vi.begin(), vi.end(), fun1 ); //To samo bez konieczno±ci tworzenia Fun1 for_each(vi.begin(), vi.end(), bind(&point::move, ref(p), _1, _1 ) ); ( rednio) zaawansowane programowanie w C++ (ZPR) 30/35
bind bind - przykªady (3) class Foo { { public: void add(double d); //wykorzystuje bind void addcollection(const std::vector<double>& v) { for_each( v.begin(), v.end(), bind(&foo::add, this, _1 ) ); } //... }; //inny sposób dostarczenia operacji dla kolekcji void addcollection(const std::vector<double>& v, Foo& foo) { for_each( v.begin(), v.end(), bind(&foo::add, ref(foo), _1 ); } ( rednio) zaawansowane programowanie w C++ (ZPR) 31/35
bind bind - kompozycja bind( f, bind(g, _1))(x) //f (g(x)) zast puje std::compose1 oraz std::compose2 int f(int x); //funkcja wykorzystywana w przykªadach vector<int> v; //znajduje element mniejszy ni» 5 find_if( v.begin(), v.end(), bind( std::less<int>(), _1, 5 ) ); //zwraca iterator do elementu x, dla którego x < f(x) find_if( v.begin(), v.end(), bind( std::less<int>(), _1, bind(f, _1))); ( rednio) zaawansowane programowanie w C++ (ZPR) 32/35
bind Przeci»anie operatorów oper obiekt funkcyjny STL! std::logical_not == std::equal_to!= std::not_equal_to < std::less <= std::less_equal > std::greater >= std::greater_equal //Przykªad struct Prac { string nazw; int wiek; int pensja; }; vector<prac> p; //Sortuje po wieku sort( p.begin(), p.end(), bind( less<int>(), bind(&prac::wiek,_1), //wi zanie skªadowej bind(&prac::wiek,_2)) ); //Sortowanie po pensji sort(p.begin(), p.end(), bind(&prac::pensja,_1) < bind(&prac::pensja,_2)); ( rednio) zaawansowane programowanie w C++ (ZPR) 33/35
bind bind - podsumowanie tworzy max 9 argumentów wi zanie dla funkcji metod dla obiektu metod dla wska¹nika do obiektu metod dla sprytnego wska¹nika do obiektu kompozycja operatory zast puj niektóre obiekty funkcyjne z STL ( rednio) zaawansowane programowanie w C++ (ZPR) 34/35
bind Dzi kuj ( rednio) zaawansowane programowanie w C++ (ZPR) 35/35