350 likes | 513 Views
STL - Standard Template Library 2 (STL od źródeł , czyli specyfikacja biblioteki). Autor: Błażej Chodarcewicz rainbow.mimuw.edu.pl/~bc189380/STL/. Standard C++ (STL). Organizacja pracująca nad standardem http://anubis.dkuug.dk/jtc1/sc22/wg21/ Wersja Draft 1996 r.
E N D
STL - Standard Template Library 2(STL od źródeł, czyli specyfikacja biblioteki) Autor: Błażej Chodarcewicz rainbow.mimuw.edu.pl/~bc189380/STL/
Standard C++ (STL) • Organizacja pracująca nad standardem http://anubis.dkuug.dk/jtc1/sc22/wg21/ • Wersja Draft 1996 r. • ISO-IEC14882Programming.Language.C++(1998) • ISO/IEC14882:2003
Iteratory • Uogólnienie wstaźników • Umożliwiają pracę z kontenerami w ujednolicony sposób • Biblioteka formalizuje interfejs, semantykę oraz założenia złożonościowe • Semantyka iteratorów jest uogólnieniem semantyki wskaźników • Wyrażenie *i – wartością jest obiekt pewnej klasy, enumeracja lub typ wbudowany T, zwany value type of iterator • Wszystkie iteratory i, dla których (*i).m jest zdefiniowane, wspierają także wyrażenie i->m • Dla każdego iteratora typu X, dla którego zdefiniowana jest równość, jest dostępny typ difference type iteratora
Rodzaje iteratorów • input iterators • output iterators • forward iterators • bidirectional iterators • random access iterators
Relacje pomiędzy iteratorami Input Output Forward Bidirectional Random Access
Iteratory zmienialne i niezmienialne • mutable, constant iterators • *i jako referencja lub referencja do stałej • Iteratory stałe nie spełniają wymagań output iterators
past-the-end value • Dla każdego iteratora istnieje wartość wskazująca na element za ostatnim elementem kolekcji, z którą związany jest iterator • dereferencable values • Biblioteka nigdy nie zakłada, że past-the-end value jest dereferencable
Kilka definicji • Iterator i jest reachable z iteratora i wtw., gdy istnieje skończona sekwencja aplikacji wyrażenia ++i, po której mamy i == j. • Jeśłi i jest reachable z j, to i i j odnoszą się do tej samej kolekcji • Range – para iteratorów, które określają początek i koniec obliczeń • Range [i, i) – empty range • W ogólności range [i, j) odnosi się do elementów struktury danych zaczynających się od elementu wskazywanego przez i, kończących się na elemencie wskazywanym przez j bez tego elementu • Range [i, j) jest prawidłowe wtw., gdy j jest reachable z i. Aplikacja algorytmu dla nieprawidłowego Range jest nieokreślona
Kilka założeń • Złożoność (zamortyzowana) wszystkich operacji wymaganych dla danej kategorii iteratora jest stała • Na następnych slajdach występują: a, b oznaczają wartości iteratora X, n oznacza wartość typu difference type Distance; u, tmp i m oznaczają identyfikatory, r oznacza wartość X&, t oznacza wartość typu wartości iteratora - T.
Input iterator – uwagi • a == b nie implikuje ++a == ++b • Algorytmy nigdy nie powinny próbować przechodzi po tym samym iteratorze dwa razy • Typ wartości T nie musi być typem lvalue (Przykład istream_iterator)
Output iterator - uwagi • operator * może zostać użyty jedynie po lewej stronie wyrażenia przypisania • przypisanie poprzez wartość iteratora odbywa się tylko raz • nigdy nie należy przechodzić po tych samych wartościach iteratora więcej niż raz • == i != mogą być niezdefiniowane
Przykłady int main(){ int array [1000], *i; int n = 0; i = array; while (cin >> *i) ++i; ++i; sort (array, i); for (j = array; i != j; j++) cout << *j << "\n"; }
Przykład int main () { vector<int> v; int input; while (cin >> input) v.push_back (input); sort(v.begin(), v.end()); for (vector<int>::iterator i = v.begin(); i != v.end(); i++) cout << *i << "\n"; }
Obiekty funkcyjne • Obiekty funkcyjne to obiekty, które mają zdefiniowany operator () • Są ważną częścią biblioteki STL, zapewniają one efektywność • Wszędzie tam, gdzie szablony algorytmów oczekują wskaźników do funkcji, można stosować obiekty funkcyjne • Używanie obiektów funkcyjnych razem z szablonami funkcji zwiększa siłę wyrazu biblioteki, a także zwiększa efektywność kodu
Obiekty funkcyjne – przykłady • dodanie elementów dwóch wektorów (double) a, b do siebietransform(a.begin(), a.end(), b.begin(), a.begin(), plus<double>()); • zanegowanie wszystkich elementów a:transform(a.begin(), a.end(), a.begin(), negate<double>());
Obiekty funkcyjne template <class Arg, class Result> struct unary_function { typedef Arg argument_type; typedef Result result_type; }; template <class Arg1, class Arg2, class Result> struct binary_function { typedef Arg1 first_argument_type; typedef Arg2 second_argument_type; typedef Result result_type; };
Obiekty funkcyjne – przykłady • template <class T> struct plus : binary_function<T,T,T> { T operator()(const T& x, const T& y) const; }; Obiekt funkcyjny obliczający x + y. • template <class T> struct negate : unary_function<T,T> { T operator()(const T& x) const; }; Obiekt funkcyjny obliczający –x.
Obiekty funkcyjne – przykłady • template <class Operation> class binder1st : public unary_function<Operation::second_argument_type, Operation::result_type> { protected: Operation op; Operation::first_argument_type value; public: binder1st(const Operation& x, const Operation::first_argument_type& y); result_type operator()(const argument_type& x) const; }; • Konstruktor inicjalizuje op na x, value na y • Operator () zwraca op(value, x) • template <class Operation, class T> binder1st<Operation> bind1st(const Operation& op, const T& x);
EqualityComparable • Typ T jest EqualityComparable jeśli ma zdefiniowany operator ==, którego wynik jest konwertowalny do bool oraz • == jest relacją równości spełniającą założenia:- Dla każdego a: a == a- Jeśli a == b, to b == a- Jeśli a == b i b == c, to a == c
Algorytmy Non-mutating • template <class InputIterator, class UnaryFunction> UnaryFunction for_each(InputIterator first, InputIterator last, UnaryFunction f);Efekt: Zaaplikowanie f do wyników dereferencii kolejnych wartości iteratora w przedziale [first, last), zaczynając od first i kontynuując aż do last - 1. Wymagania: f nie powinno wywoływać żadnych funkcji, które nie są zadeklarowane jako stałe dla wartości iteratora. Zwraca: f. Złożoność: f jest wywoływana dokładnie last - first razy. Uwaga: Jeśli f zwraca jakąś wartość wynik jest ignorwany. • template <class InputIterator, class EqualityComparable>iterator_traits<InputIterator>::difference_type count(InputIterator first, InputIterator last, const EqualityComparable& value);Wymagania: Typ T jest EqualityComparable.Efekt: Zwraca liczbę iteratorów i z przedziału [first, last), dla których warunek: *i == value.
Algorytmy Non-mutating • template<class InputIterator, class EqualityComparable> InputIterator find(InputIterator first, InputIterator last, const EqualityComparable& value)Wymagania: Typ T is EqualityComparable.Wynik: Pierwszy iterator i z przedziału [first, last), dla którego prawdziwy jest warunek: *i == value. Jeśli żaden iterator z tego przedziału nie spełnia tego warunku zwracany jest last. • template<class InputIterator, class OutputIterator> OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result); Efekt: kopiuje elementy z przedziału [first, last) do [result, result+(last-first)) zaczynając od first i kontynuując aż do last. Dla każdej nieujemnej liczby n < (last-first), wykonuje *(result+n) = *(first+n). Wynik: result + (last - first). Wymagania: result nie powinien być z przedziału [first, last). Złożoność: dokładnie last - first przypisań.
Przykład: template<class T> struct print : public unary_function<T, void>{ print(ostream& out) : os(out), count(0) {} void operator() (T x) { os << x << ' '; ++count; } ostream& os; int count; }; int main(){ int A[] = {1, 4, 2, 8, 5, 7}; const int N = sizeof(A) / sizeof(int); print<int> P = for_each(A, A + N, print<int>(cout)); cout << endl << P.count << " objects printed." << endl; }
Gdzie szukać informacji? • Musser Saini, STL Tutorial and Reference • Lippman, "Istota jezyka C++„ • N.M.Josuttis, C++ bibliotek standardowa podrecznik programisty • www-d0.fnal.gov/~dladams/cxx_standard.pdf • http://anubis.dkuug.dk/jtc1/sc22/open/n2356/
Gdzie szukać informacji? • http://www.sgi.com/tech/stl/ - implementacja STL firmy Silicon Graphics, Inc. (SGI) • http://www.informatik.hs-bremen.de/~brey/stlbe.html - książka "Designing Components with the C++ STL" • http://www.xraylith.wisc.edu/~khan/software/stl/STL.newbie.html - strona o STL z 1995 roku • http://www.cs.brown.edu/people/jak/proglang/cpp/stltut/tut.html - prosty tutorial • http://www.cs.rpi.edu/~wiseb/xrds/ovp2-3b.html - krótki opis STL'a • http://pages.cpsc.ucalgary.ca/~kremer/STL/1024x768/index.html - strona o STL'u