Wyklad 13: STL

49
Standard Template Standard Template Library Library

Transcript of Wyklad 13: STL

Standard Template Standard Template LibraryLibrary

Książki o STLKsiążki o STL Nicolai M. Josuttis: C++ Biblioteka standardowa Nicolai M. Josuttis: C++ Biblioteka standardowa

Podręcznik Programisty, Helion 2003, Podręcznik Programisty, Helion 2003, przykłady: przykłady: ftp://ftp.helion.pl/przyklady/cpbspp.zipftp://ftp.helion.pl/przyklady/cpbspp.zip

Grębosz J.: Pasja C++, RM, W-waGrębosz J.: Pasja C++, RM, W-wa Inne (wymienione na wykładzie Nr 1)Inne (wymienione na wykładzie Nr 1)

Biblioteka standardowa języka C++Biblioteka standardowa języka C++

STLSTL

Klasy strumienioweKlasy strumieniowe Klasy łańcuchoweKlasy łańcuchowe

(biblioteka zdefiniowana w namespace std )(biblioteka zdefiniowana w namespace std )

Biblioteka standardowa języka C++Biblioteka standardowa języka C++ Główne składnikiGłówne składniki

KonteneryKontenery (listy, wektory, etc.) (listy, wektory, etc.) IteratoryIteratory (interfejs pomiędzy algorytmami a kontenerami) (interfejs pomiędzy algorytmami a kontenerami) AlgorytmyAlgorytmy (proste, nie bardziej skomplikowane od wyszukiwania i (proste, nie bardziej skomplikowane od wyszukiwania i

sortowanie)sortowanie) Inne (obiekty funkcyjne, adaptory, szablony pomocnicze...)Inne (obiekty funkcyjne, adaptory, szablony pomocnicze...)

STL to biblioteka STL to biblioteka wzorcówwzorców!! Dane odseparowane od metod (a co z ideą OOP?)Dane odseparowane od metod (a co z ideą OOP?) Zaprojektowane dla programowania wysokopoziomowegoZaprojektowane dla programowania wysokopoziomowego Zaprojektowane dla programowania wydajnegoZaprojektowane dla programowania wydajnego

BTW: rząd złożoności algorytmuBTW: rząd złożoności algorytmu

O-notacjaO-notacja

Wyszukiwanie w posortowanej tablicy:Wyszukiwanie w posortowanej tablicy: O(logO(log22((nn)))) Wyszukiwanie w nieuporządkowanej tablicy: Wyszukiwanie w nieuporządkowanej tablicy: O(O(nn)) Quicksort:Quicksort: O(O(nn ·· log log22((nn)))) Sortowanie bąbelkowe:Sortowanie bąbelkowe: O(O(nn22))

KonteneryKontenery SekwencyjneSekwencyjne

vector (tablica dynamiczna)vector (tablica dynamiczna) dequeue (tablica dynamiczna dwukierunkowa)dequeue (tablica dynamiczna dwukierunkowa) list (lista dwukierunkowa)list (lista dwukierunkowa)

array (C++11) – tablica o stałym rozmiarzearray (C++11) – tablica o stałym rozmiarze forward_list (C++11) – lista jednokierunkowaforward_list (C++11) – lista jednokierunkowa

tablica i string --- nie są kontenerami STL, ale można je tablica i string --- nie są kontenerami STL, ale można je przetwarzać za pomocą algorytmów STLprzetwarzać za pomocą algorytmów STL

adaptery kontenerówadaptery kontenerów stack (kolejka LIFO), queue (kolejka FIFO), priority_queuestack (kolejka LIFO), queue (kolejka FIFO), priority_queue

Kontenery asocjacyjneKontenery asocjacyjne Asocjacyjne Asocjacyjne

set (drzewo binarne)set (drzewo binarne) multisetmultiset map, multimapmap, multimap

Asocjacyjne nieuporządkowane (C++11)Asocjacyjne nieuporządkowane (C++11)(zaimplementowane za pomoca tablicy mieszającej zamiast drzewa binarnego, (zaimplementowane za pomoca tablicy mieszającej zamiast drzewa binarnego,

w starszych implementacjach znane jako hash_*)w starszych implementacjach znane jako hash_*) unordered_set, unordered_multiset, unordered_set, unordered_multiset, unordered_map, unordered_multimapunordered_map, unordered_multimap

KonteneryKontenery vector vector

Zaimplementowany jako tablica dynamicznaZaimplementowany jako tablica dynamiczna

szybkie push_back()szybkie push_back() szybki operator[]szybki operator[]

wolne insert()wolne insert()

KonteneryKontenery deque deque

Zaimplementowany jako tablica dynamicznaZaimplementowany jako tablica dynamiczna

szybkie push_back() szybkie push_back() (vector może być szybszy)(vector może być szybszy) szybkie push_front() szybkie push_front() (nieobsługiwany przez vector)(nieobsługiwany przez vector) szybki operator[]szybki operator[]

wolny insert()wolny insert()

KonteneryKontenery list list

Zaimplementowana jako lista Zaimplementowana jako lista dwukierunkowadwukierunkowa

szybkie push_back()szybkie push_back() szybkie push_front()szybkie push_front() szybkie insert()szybkie insert()

Nie ma operatora operator[]Nie ma operatora operator[]

przykład: list1.cppprzykład: list1.cpp

IteratoryIteratory Iteratory zachowują się jak zwyczajne wskaźniki ...Iteratory zachowują się jak zwyczajne wskaźniki ...

* * ->-> ++++ ---- ==== !=!= == (vector, deq: -, <, >, +(int) )(vector, deq: -, <, >, +(int) )

Ale działają dla wszystkich kontenerów!Ale działają dla wszystkich kontenerów! container.begin()container.begin() // zwróć iterator do pierwszego elementu.// zwróć iterator do pierwszego elementu. container.end()container.end() // ... do ostatniego// ... do ostatniego

przykład: list2.cppprzykład: list2.cpp

Kontenery asocjacyjneKontenery asocjacyjne set set

Zaimplementowany jako drzewo binarneZaimplementowany jako drzewo binarne Sowrtowanie przy wstawianiu (porównywanie domyślnym Sowrtowanie przy wstawianiu (porównywanie domyślnym

operatorem<() )operatorem<() ) Odpowiednik zbiorów matematycznychOdpowiednik zbiorów matematycznych

metoda find()metoda find()

szybkie insert()szybkie insert()

nie ma: push_back()nie ma: push_back() nie ma: push_front()nie ma: push_front() nie ma: operatora []nie ma: operatora []

Kontenery asocjacyjneKontenery asocjacyjne multiset multiset

Dozwolone powtórzenia tej samej wartościDozwolone powtórzenia tej samej wartości Uporządkowanie wewnątrz grupy elementów o Uporządkowanie wewnątrz grupy elementów o

tych samych wartościach jest niezdefiniowanetych samych wartościach jest niezdefiniowane

Kontenery asocjacyjneKontenery asocjacyjne multimapmultimap

multiset dla par: klucz, wartość – użyj make_pair() multiset dla par: klucz, wartość – użyj make_pair()

Kontenery asocjacyjneKontenery asocjacyjne mapmap

set dla par: klucz, wartość – użyj make_pair()set dla par: klucz, wartość – użyj make_pair()

Tylko dla kontenera mapTylko dla kontenera map: operator[key](): operator[key]() Indeksowanie wartością (tablica asocjacyjna) Indeksowanie wartością (tablica asocjacyjna)

Adaptery kontenerówAdaptery kontenerów stack (kolejka LIFO)stack (kolejka LIFO) queue (kolejka FIFO)queue (kolejka FIFO) priority_queue (kolejka priorytetowa)priority_queue (kolejka priorytetowa)

stackstack header <stack>header <stack> prosta koleja LIFO zaimplementowana za pomocą dequeprosta koleja LIFO zaimplementowana za pomocą deque

może być oparta o kontener mający: back(), push_back(), pop_back()może być oparta o kontener mający: back(), push_back(), pop_back() wystarczy podać 2gi argument szablonu, np.: stack<int, vector<int>>wystarczy podać 2gi argument szablonu, np.: stack<int, vector<int>>

po prostu przekierowuje swoje metody do deque aby uzyskać kolejkę LIFOpo prostu przekierowuje swoje metody do deque aby uzyskać kolejkę LIFO example: cont/stack1.cppexample: cont/stack1.cpp

push()push() pop()pop() top() top() // pobierz wartość elementu ze szczytu stosu// pobierz wartość elementu ze szczytu stosu

// ale nie usuwaj go// ale nie usuwaj go size()size() // zwróć rozmiar stosu // zwróć rozmiar stosu empty()empty() // czy stos jest pusty? // czy stos jest pusty? operatory : ==, !=, <, >, <=, >= operatory : ==, !=, <, >, <=, >= // == zwraca 1 gdyrozmiary i elementy // == zwraca 1 gdyrozmiary i elementy

identyczneidentyczne bez innych metod lub operatorówbez innych metod lub operatorów

queue queue header <queue>header <queue> prosta kolejka FIFO zaimplementowana za pomocą dequeprosta kolejka FIFO zaimplementowana za pomocą deque

może być oparta o kontener mający : front(), back(), push_back(), pop_front()może być oparta o kontener mający : front(), back(), push_back(), pop_front() wystarczy podać 2gi argument szablonu, np.: queue<int, list<int>>wystarczy podać 2gi argument szablonu, np.: queue<int, list<int>>

po prostu przekierowuje swoje metody do deque aby uzyskać kolejkę FIFOpo prostu przekierowuje swoje metody do deque aby uzyskać kolejkę FIFO przykład: cont/queue1.cppprzykład: cont/queue1.cpp

push()push() pop()pop() back() back() // zwróć wartość ostatnio wstawionego elementu// zwróć wartość ostatnio wstawionego elementu

// ale go nie usuwaj// ale go nie usuwaj front() front() // zwróć wartość elementu z przodu kolejni// zwróć wartość elementu z przodu kolejni

// ale go nie usuwaj// ale go nie usuwaj size()size() // zwróć rozmiar stosu // zwróć rozmiar stosu empty()empty() // czy stos jest pusty? // czy stos jest pusty? operatory: ==, !=, <, >, <=, >=operatory: ==, !=, <, >, <=, >= // == zwraca 1 rozmiary i elementy // == zwraca 1 rozmiary i elementy

identyczneidentyczne bez innych metod lub operatorówbez innych metod lub operatorów

priority_queue priority_queue header <queue>header <queue> prosta kolejka priorytetowa zaimplementowana za pomocą vectorprosta kolejka priorytetowa zaimplementowana za pomocą vector

może być oparta o kontener mający: front(), push_back(), pop_front(), operator[]może być oparta o kontener mający: front(), push_back(), pop_front(), operator[] wystarczy podać 2gi argument szablonu, np.: priority_queue<int, deque<int>>wystarczy podać 2gi argument szablonu, np.: priority_queue<int, deque<int>> 3ci argument to kryterium sortowania (domyślnie: operator< )3ci argument to kryterium sortowania (domyślnie: operator< )

priority_queue<int, vector<int>, greater<int>>priority_queue<int, vector<int>, greater<int>> przekierowuje swoje metody do metod kontenera vectorprzekierowuje swoje metody do metod kontenera vector przykład: cont/pqueue1.cppprzykład: cont/pqueue1.cpp

push()push() pop()pop() top() top() // zwróć wartość elementu o największym priorytecie// zwróć wartość elementu o największym priorytecie

// ale go nie usuwaj z kolejki// ale go nie usuwaj z kolejki size()size() // liczba elementów// liczba elementów empty()empty() // czy kolejka pusta // czy kolejka pusta bez innych metod lub operatorów (w tym operatora ==, etc.)bez innych metod lub operatorów (w tym operatora ==, etc.)

Algorytmy STLAlgorytmy STL Operują na kontenerach za pomocą iteratorówOperują na kontenerach za pomocą iteratorów

Sposób uniwersalny, ale nie tak szybki jak metody kontenerówSposób uniwersalny, ale nie tak szybki jak metody kontenerów Dla niektórych kombinacji algorytm/kontener wolneDla niektórych kombinacji algorytm/kontener wolne Możliwe jednoczesne działanie na kontenerach różnych typówMożliwe jednoczesne działanie na kontenerach różnych typów

Tylko podstawowe, proste algorytmyTylko podstawowe, proste algorytmy Parametryzowalne przez rozmaite iteratoryParametryzowalne przez rozmaite iteratory Parametryzowalne przez obiekty funkcyjne i adaptoryParametryzowalne przez obiekty funkcyjne i adaptory

Bardziej podatne na błędy programisty od metod kontenerówBardziej podatne na błędy programisty od metod kontenerów

Algorytmy STLAlgorytmy STL Przykład: algo1.cppPrzykład: algo1.cpp

min_elementmin_element // operator<()// operator<() max_elementmax_element // operator<()// operator<() sortsort // operator<()// operator<() findfind // operator==()// operator==() reversereverse // operator=()// operator=()

min_element (coll.begin(), coll.end())min_element (coll.begin(), coll.end()) Zakres to Zakres to [[ coll.begin(), coll.end() coll.begin(), coll.end() )) ((przykład: find1.cppprzykład: find1.cpp)) Właściwa definicja zakresu to zadanie programistyWłaściwa definicja zakresu to zadanie programisty Koniec zakresu powinien być osiągany przez ++’owanie początkuKoniec zakresu powinien być osiągany przez ++’owanie początku Co gdy nie mamy pewności co jest końcem a co początkiem?Co gdy nie mamy pewności co jest końcem a co początkiem?

DygresjaDygresja// bez algorytmu, pre - C++11// bez algorytmu, pre - C++11list<char>::const_iterator pos;list<char>::const_iterator pos;for (pos = coll.begin(); pos != coll.end(); ++pos)for (pos = coll.begin(); pos != coll.end(); ++pos)

cout << *pos << ' ';cout << *pos << ' ';

// nadal bez algorytmu, C++11: auto i for zakresowe// nadal bez algorytmu, C++11: auto i for zakresowefor (const auto & car : coll)for (const auto & car : coll)

cout << car << ' ';cout << car << ' ';

// algorytm i funkcja lambda - rozwiązanie preferowane// algorytm i funkcja lambda - rozwiązanie preferowanefor_each(coll.begin(), coll.end(), for_each(coll.begin(), coll.end(),

[](const auto & car) { cout << car << ' '; });[](const auto & car) { cout << car << ' '; });

Algorytmy STLAlgorytmy STL copy (coll1.begin(), coll1.end(), coll2.begin()); copy (coll1.begin(), coll1.end(), coll2.begin());

Koniec zakresu podany tylko dla pierwszego zakresuKoniec zakresu podany tylko dla pierwszego zakresu Rozmiar zakresu docelowego Rozmiar zakresu docelowego musimusi być wystarczający być wystarczający

Algorytm przeprowadza wyłącznie proste nadpisywanieAlgorytm przeprowadza wyłącznie proste nadpisywanie … … bez sprawdzania rozmiaru zakresu docelowegobez sprawdzania rozmiaru zakresu docelowego

(iteratory to interfejs do elementów kontenera, nie do kontenera)(iteratory to interfejs do elementów kontenera, nie do kontenera) Właściwy rozmiar kolekcji to odpowiedzialność/zadanie Właściwy rozmiar kolekcji to odpowiedzialność/zadanie

programisty programisty ((przykład: copy2.cppprzykład: copy2.cpp)) Dla niektórych kontenerów (sekwencyjne) ustawienie rozmiaru Dla niektórych kontenerów (sekwencyjne) ustawienie rozmiaru

początkowego jest prostepoczątkowego jest proste

Iteratory STLIteratory STL Wielkość zakresu musi być wystarczająca, albo ...Wielkość zakresu musi być wystarczająca, albo ... copy (coll1.begin(), coll1.end(),copy (coll1.begin(), coll1.end(),

inserter(inserter(coll2coll2, coll2.begin(), coll2.begin())) ); );

... albo użyj iteratorów wstawiających (inserter) ;) ... albo użyj iteratorów wstawiających (inserter) ;) ((copy3.cppcopy3.cpp)) inserter dla wszystkich kontenerów, które mają metodę insert()inserter dla wszystkich kontenerów, które mają metodę insert()

Wstawia przed podaną lokalizacjąWstawia przed podaną lokalizacją Dla kontenerów asocjacyjnych lokalizacja jest tylko wskazówkąDla kontenerów asocjacyjnych lokalizacja jest tylko wskazówką

back_inserter dla kontenerów, które mają metodę push_back()back_inserter dla kontenerów, które mają metodę push_back() front_inserter dla kontenerów, które mają metodę push_front()front_inserter dla kontenerów, które mają metodę push_front()

Iteratory STLIteratory STL Iteratory strumienioweIteratory strumieniowe

Zachowują się jak zwyczajne iteratoryZachowują się jak zwyczajne iteratory Mają interfejs zwykłych iteratorówMają interfejs zwykłych iteratorów

Operują na strumieniach i/o Operują na strumieniach i/o (ioiter1.cpp)(ioiter1.cpp) istream_iterator<string>(cin) istream_iterator<string>(cin)

++iter dla stream>>temp, *iter aby pobrać temp++iter dla stream>>temp, *iter aby pobrać temp istream_iterator<string>()istream_iterator<string>()

Iterator końca srtumienia (zakresu strumienia)Iterator końca srtumienia (zakresu strumienia)

Iteratory STLIteratory STL Iteratory odwrotne (reverse iterator)Iteratory odwrotne (reverse iterator)

Mają interfejs zwykłych iteratorówMają interfejs zwykłych iteratorów Zachowują się odwrotnie Zachowują się odwrotnie (rter1.cpp)(rter1.cpp)

container.rbegin() wskazuje na ostatni element container.rbegin() wskazuje na ostatni element (nie pozycję (nie pozycję popo ostatnim) ostatnim)

container.rend() wskazuje na pozycję przed pierwszym!container.rend() wskazuje na pozycję przed pierwszym! ++ to --, -- to ++, itd. ++ to --, -- to ++, itd.

Algorytmy STLAlgorytmy STL Usuwanie elementów z kontenera Usuwanie elementów z kontenera

Algorytm remove(...)Algorytm remove(...) Tak naprawdę nie usuwa zawartości kontenera Tak naprawdę nie usuwa zawartości kontenera ((remove1.cppremove1.cpp)) Nie ma dostępu do kontenera, a tylko do elementówNie ma dostępu do kontenera, a tylko do elementów Nie działa dla kontenerów asocjacyjnychNie działa dla kontenerów asocjacyjnych Zwraca nowy koniec zakresu (element następny po ostatnim)Zwraca nowy koniec zakresu (element następny po ostatnim)

Użyj metody kontener.erase(...) by się pozbyć elementów Użyj metody kontener.erase(...) by się pozbyć elementów ((remove2.cppremove2.cpp))

Wiele wersjiWiele wersji Działa dla kontenerów asocjacyjnych Działa dla kontenerów asocjacyjnych ((remove3.cppremove3.cpp))

Funkcja jako argument algorytmuFunkcja jako argument algorytmu

Funkcje jednoargumentowe Funkcje jednoargumentowe przykłady: foreach1.cpp, transform1.cppprzykłady: foreach1.cpp, transform1.cpp

Predykaty Predykaty Jeden argument i wynik bool Jeden argument i wynik bool

((przykład: prime1.cppprzykład: prime1.cpp)) Dwa argumenty i wynik bool Dwa argumenty i wynik bool

((przykład: sort1.cppprzykład: sort1.cpp))

Obiekt funkcyjny jako argument Obiekt funkcyjny jako argument algorytmualgorytmu

Obiekty funkcyjneObiekty funkcyjne Zachowują się jak funkcje, ale wykorzystują Zachowują się jak funkcje, ale wykorzystują

operator()() operator()() foreach2.cppforeach2.cpp

Są obiektamiSą obiektami Lepiej optymalizowane przez kompilator Lepiej optymalizowane przez kompilator Mogą posiadać zmienne klasowe, „wewnętrzny stan” Mogą posiadać zmienne klasowe, „wewnętrzny stan”

przekazany jako argument konstruktora przekazany jako argument konstruktora ((add1.cppadd1.cpp)) Można mieć wiele obiektów funkcyjnych tej samej Można mieć wiele obiektów funkcyjnych tej samej

klasyklasy

Obiekt funkcyjny jako argument Obiekt funkcyjny jako argument algorytmualgorytmu

Predefiniowane szablony obiektów funkcyjnychPredefiniowane szablony obiektów funkcyjnych less<>, greater <>less<>, greater <>

set<int> s;set<int> s; domyślnie oznacza domyślnie oznacza set<int, less<int> > s;set<int, less<int> > s;

można również:można również: set<int, greater<int> > s;set<int, greater<int> > s;

negate<>, multiply<> negate<>, multiply<> // do użycia w algorytmie transform(...)// do użycia w algorytmie transform(...)

Adaptory funkcjiAdaptory funkcji Definiują przypadki szczególne użycia funkcjiDefiniują przypadki szczególne użycia funkcji Modyfikują funkcję, gdy wymagany jest inny Modyfikują funkcję, gdy wymagany jest inny

interfejs (tj. lista argumentów)interfejs (tj. lista argumentów) bind2nd(less<int>(),50)bind2nd(less<int>(),50) ((fo1.cppfo1.cpp))

Tworzymy domyślny drugi argumentTworzymy domyślny drugi argument

Funkcje lambda (a.k.a. wyrażenia Funkcje lambda (a.k.a. wyrażenia lambda, „lambdy”)lambda, „lambdy”)

Lokalna, nienazwana funkcja, do użycia jako argument funkcji, szablonu (np. Algorytmów STL) Lokalna, nienazwana funkcja, do użycia jako argument funkcji, szablonu (np. Algorytmów STL) zamiast zwykłej funkcji lub obiektu funkcyjnegozamiast zwykłej funkcji lub obiektu funkcyjnego

[&](int a, int b) { return[&](int a, int b) { return v[a].name<v[b].name; }v[a].name<v[b].name; } Typ funkcji jest wnioskowany z wyrażenia return, można podać używając alternatywnej składni Typ funkcji jest wnioskowany z wyrażenia return, można podać używając alternatywnej składni

deklaracjideklaracji

[] – capture list, informuje jakie zmienne z lokalnego zakresu są widoczne w ciele funkcji lambda, [] – capture list, informuje jakie zmienne z lokalnego zakresu są widoczne w ciele funkcji lambda, [] [] – nie widać nic (z zakresu, ale widać argumenty)– nie widać nic (z zakresu, ale widać argumenty)[&] [&] – wszystko, jako referencje– wszystko, jako referencje[=] [=] – wszystko czego używa funkcja, przekazane przez zmienną– wszystko czego używa funkcja, przekazane przez zmienną

jako stała ( aby przy przekazywaniu przez zmienną móc ją jako stała ( aby przy przekazywaniu przez zmienną móc ją modyfikować należy użyć „mutable” po nawiasie modyfikować należy użyć „mutable” po nawiasie zamykającym listę argumentów f. lambda) zamykającym listę argumentów f. lambda)

[a, &c][a, &c] – zmienna a przez wartość, zmienna c jako referencja– zmienna a przez wartość, zmienna c jako referencja

Użyj funkcji lambda, jeżeli chcesz wykonać zadanie proste i typowe, do innych zadań lepsze Użyj funkcji lambda, jeżeli chcesz wykonać zadanie proste i typowe, do innych zadań lepsze funkcje i obiekty funkcyjnefunkcje i obiekty funkcyjne

Funkcje lambdaFunkcje lambda

void f(vector<Record>& v)void f(vector<Record>& v){{

vector<int> indices(v.size());vector<int> indices(v.size());int count = 0;int count = 0;generate(indices.begin(),indices.end(),generate(indices.begin(),indices.end(),

[&count](){ return count[&count](){ return count++++; }; }););

// // posortuj indeksy w kolejności określonej przez pole name rekorduposortuj indeksy w kolejności określonej przez pole name rekordu::std::sort(indices.begin(), indices.end(), std::sort(indices.begin(), indices.end(),

[&](int a, int b) { return v[a].name<v[b].name; }[&](int a, int b) { return v[a].name<v[b].name; }););// ...// ...

}}

Funkcje lambda (od C++14)Funkcje lambda (od C++14)

Argumenty funkcji mogą być typu autoArgumenty funkcji mogą być typu auto

Argumenty w capture list mogą mieć wartości domyślneArgumenty w capture list mogą mieć wartości domyślne

można w ten sposób wymusić przekazanie argumentu przez r-wartość/move można w ten sposób wymusić przekazanie argumentu przez r-wartość/move semanticssemantics

std::unique_ptr<int> ptr(new int(10)); std::unique_ptr<int> ptr(new int(10)); auto lambda = [value = std::move(ptr)] {return *value;}; auto lambda = [value = std::move(ptr)] {return *value;};

można użyć wewnątrz funkcji zmiennych niewidocznych w miejscu można użyć wewnątrz funkcji zmiennych niewidocznych w miejscu wywołania funkcji utworzonych w capture list (typ wyznaczony jak przez wywołania funkcji utworzonych w capture list (typ wyznaczony jak przez auto)auto)

auto lambda = [value = 1] {return value;}; auto lambda = [value = 1] {return value;};

STL, błędy i wyjątkiSTL, błędy i wyjątki Zaprojektowana dla maksymalizacji prędkościZaprojektowana dla maksymalizacji prędkości

W przypadku błędnego użycia (np. *end()=something) zachowanie jest W przypadku błędnego użycia (np. *end()=something) zachowanie jest niezdefiniowane, miejmy nadzieją że błąd ujawni się wcześnieniezdefiniowane, miejmy nadzieją że błąd ujawni się wcześnie

Ostrożnie z iteratorami i zakresamiOstrożnie z iteratorami i zakresami Tylko minimalne sprawdzenia są realizowane (wyjątek bad_alloc)Tylko minimalne sprawdzenia są realizowane (wyjątek bad_alloc)

Jest wersja debug bibliotekiJest wersja debug biblioteki Użyj jej!!!Użyj jej!!!

Niektóre metody niektórych kontenerów są „transaction-safe”Niektóre metody niektórych kontenerów są „transaction-safe” A niektóre nie są!A niektóre nie są! Sprawdź w dokumentacji!Sprawdź w dokumentacji!

Wybrane inne elementy bibliotekiWybrane inne elementy biblioteki Klasa bitsetKlasa bitset

Inteligentne wskaźnikiInteligentne wskaźniki auto_ptr (deprecated)auto_ptr (deprecated) unique_ptrunique_ptr shared_ptrshared_ptr weak_ptrweak_ptr

bitset bitset header header <bitset><bitset> wygodna klasa do przetwarzania pól bitowych o wygodna klasa do przetwarzania pól bitowych o

znanym rozmiarzeznanym rozmiarzebitset<20> flags;bitset<20> flags;

wykonywania bitowego i/owykonywania bitowego i/o example: cont/bitset1.cppexample: cont/bitset1.cpp

i całkowitoliczbowego i/o w formacie binarnymi całkowitoliczbowego i/o w formacie binarnym example: cont/bitset2.cppexample: cont/bitset2.cpp

bez konstruktora kopiującego i op. przypisaniabez konstruktora kopiującego i op. przypisania

bitsetbitset bitset - konstruktorybitset - konstruktory

bitset<bits>::bitset() bitset<bits>::bitset() bitset<bits>::bitset(unsigned long val)bitset<bits>::bitset(unsigned long val)bitset<bits>::bitset(const string &sc)bitset<bits>::bitset(const string &sc)// bez inicjalizacji char*, kilka wariantów inicjalizacji string-iem// bez inicjalizacji char*, kilka wariantów inicjalizacji string-iem

metody i operatory klasy bitsetmetody i operatory klasy bitsetsize() size() // rzwróć rozmiar bitset-u// rzwróć rozmiar bitset-ucount() count() // policz jedynki// policz jedynkiany() any() // 1 jeżeli przynajmniej 1 bit ustawiony// 1 jeżeli przynajmniej 1 bit ustawionynone() none() // !any()// !any()test(size_t idx) test(size_t idx) // czy bit o indeksjie idx jest ustawiony?// czy bit o indeksjie idx jest ustawiony?operator==(const bitset<bits>& arg) operator==(const bitset<bits>& arg) operator!=(const bitset<bits>& arg) operator!=(const bitset<bits>& arg) … …

bitsetbitset metody i operatory klasy bitsetmetody i operatory klasy bitset

set() set() // ustaw wszystkie bity na jedynki// ustaw wszystkie bity na jedynkiset(size_t idx, int value=1) set(size_t idx, int value=1) reset() reset() // wszystkie na 0// wszystkie na 0reset(size_t idx)reset(size_t idx) // bit o indeksie idx na 0// bit o indeksie idx na 0flip() flip() // zaneguj wszystkie bity// zaneguj wszystkie bityflip(size_t idx) flip(size_t idx)

bitowe operatory (rozmiary argumentów muszą pasować): bitowe operatory (rozmiary argumentów muszą pasować): ^= |= &= ^ | & ~^= |= &= ^ | & ~bitowe przesunięcia (bitowe przesunięcia (size_tsize_t argument): argument): <<= << >>= >><<= << >>= >>

operatory łańcuchowe: operatory łańcuchowe: << >><< >>

bool operator[] (size_t idx) const bool operator[] (size_t idx) const // zachowanie niezdefiniowane gdy idx poza zasięgiem// zachowanie niezdefiniowane gdy idx poza zasięgiembitset<bits>::reference operator[] (size_t idx) bitset<bits>::reference operator[] (size_t idx) // zwróć obiekt specjalnego typu (tzw. proxy)// zwróć obiekt specjalnego typu (tzw. proxy)// za pomocą którego następnie można: =(bool), =(const reference &), flip(), operator~(), bool()// za pomocą którego następnie można: =(bool), =(const reference &), flip(), operator~(), bool()

to_ulong(), to_string()to_ulong(), to_string()

Inteligentne wskaźnikiInteligentne wskaźniki auto_ptrauto_ptr

ścisła własność wskazywanej danej, deprecatedścisła własność wskazywanej danej, deprecated

unique_ptrunique_ptr ścisła własność wskazywanej danej, od C++11 zastępuje ścisła własność wskazywanej danej, od C++11 zastępuje auto_ptrauto_ptr

shared_ptrshared_ptr współdzielony wskaźnik ze zliczaniem referencji do wskazywanego obiektuwspółdzielony wskaźnik ze zliczaniem referencji do wskazywanego obiektu

weak_ptrweak_ptr pomocniczy wskaźnik do danych zarządzanych przez pomocniczy wskaźnik do danych zarządzanych przez shared_ptrshared_ptr do przerywania pętli zależności do przerywania pętli zależności shared_ptrshared_ptr

Inteligentne wskaźnikiInteligentne wskaźniki

auto_ptrauto_ptr ścisła własność wskazywanej danejścisła własność wskazywanej danej niezgodny z metodami przenoszącymi C++11niezgodny z metodami przenoszącymi C++11 niezgodny z kontenerami i algorytmami STLniezgodny z kontenerami i algorytmami STL zachowany dla zgodności w dół, deprecatedzachowany dla zgodności w dół, deprecated zamiast niego użyj zamiast niego użyj unique_ptrunique_ptr!!

Inteligentne wskaźnikiInteligentne wskaźniki unique_ptrunique_ptr

ścisła własność wskazywanej danejścisła własność wskazywanej danej zastępuje zastępuje auto_ptrauto_ptr sprzed C++11 sprzed C++11 jego destruktor niszczy wskazywaną danąjego destruktor niszczy wskazywaną daną bez konstruktora kopiującego i operatora przypisaniabez konstruktora kopiującego i operatora przypisania z konstruktorem przenoszącym i operatorem przeniesienia z konstruktorem przenoszącym i operatorem przeniesienia podobnie jak podobnie jak auto_ptrauto_ptr może być użyty do tworzenia źródeł i może być użyty do tworzenia źródeł i

ujść danych, unikania wycieków pamięci w przerywanych ujść danych, unikania wycieków pamięci w przerywanych podprogramach (włączając konstruktory)podprogramach (włączając konstruktory)

w przeciwieństwie do w przeciwieństwie do auto_ptr auto_ptr bezpieczny z algorytmami i bezpieczny z algorytmami i kontenerami STLkontenerami STL

Inteligentne wskaźnikiInteligentne wskaźniki Przykład: zwykły wskaźnik a wyjątki Przykład: zwykły wskaźnik a wyjątki

X* f() X* f() { {

X* p = new X; X* p = new X;

// tu kod mogący wyrzucić wyjątek// tu kod mogący wyrzucić wyjątek

return p; return p; } }

Inteligentne wskaźnikiInteligentne wskaźniki Przykład: odpowiednik bezpieczny w przypadku wyjątkuPrzykład: odpowiednik bezpieczny w przypadku wyjątku

X* f() X* f() { {

unique_ptr<X>unique_ptr<X> p(new X); p(new X); // albo {new X} ale nie = new X // albo {new X} ale nie = new X

// tu kod mogący wyrzucić wyjątek// tu kod mogący wyrzucić wyjątek

return p.release(); return p.release(); } }

Inteligentne wskaźnikiInteligentne wskaźniki Przykład: źródło danych, bezpieczne w przypadku wyjątkuPrzykład: źródło danych, bezpieczne w przypadku wyjątku

unique_ptr<X> f() unique_ptr<X> f() { {

unique_ptr<X>unique_ptr<X> p(new X); p(new X); // albo {new X} ale nie = new X // albo {new X} ale nie = new X

// tu kod mogący wyrzucić wyjątek// tu kod mogący wyrzucić wyjątek

return p; return p; // własność jest przenoszona poza f() // własność jest przenoszona poza f()

} }

Inteligentne wskaźnikiInteligentne wskaźniki shared_ptrshared_ptr

współdzielony wskaźnik ze zliczaniem referencji do współdzielony wskaźnik ze zliczaniem referencji do wskazywanego obiektu ...wskazywanego obiektu ...

... oraz wspólną własnością obiektu przez wszystkie ... oraz wspólną własnością obiektu przez wszystkie shared_ptr shared_ptr odnoszące się do niego ...odnoszące się do niego ...

... i poprawnym działaniem w środowisku wielowątkowym... i poprawnym działaniem w środowisku wielowątkowym tworzone wskaźniki tworzone wskaźniki shared_ptrshared_ptr do tej samej danej są zliczane do tej samej danej są zliczane

w sposób szybki i prostyw sposób szybki i prosty nowy wskaźnik do określonej danej jest tworzony za pomocą innego nowy wskaźnik do określonej danej jest tworzony za pomocą innego

wskaźnika na tę daną, który już istnieje (przykład dalej)wskaźnika na tę daną, który już istnieje (przykład dalej) przy destrukcji przy destrukcji shared_ptrshared_ptr licznik referencji jest licznik referencji jest

dekrementowany dekrementowany gdy osiągnie 0 wskazywana dana jest destruowanagdy osiągnie 0 wskazywana dana jest destruowana

Inteligentne wskaźnikiInteligentne wskaźniki

void test() void test() { {

shared_ptr<int>shared_ptr<int> p1(new int); // licznik wynosi 1 p1(new int); // licznik wynosi 1 { {

shared_ptr<int>shared_ptr<int> p2(p1); // licznik wynosi 2 p2(p1); // licznik wynosi 2 { {

shared_ptr<int>shared_ptr<int> p3(p1); // licznik wynosi 3 p3(p1); // licznik wynosi 3 // licznik powraca do 2 // licznik powraca do 2

} // licznik powraca do 1 } // licznik powraca do 1 } // licznik staje sie 0 i int jest zwalniany} // licznik staje sie 0 i int jest zwalniany

Inteligentne wskaźnikiInteligentne wskaźniki shared_ptr shared_ptr wg. Stroustroup’a nie jest uniwersalnym zastępcą wg. Stroustroup’a nie jest uniwersalnym zastępcą

zwykłego wskaźnika, ze względu na poniższe koszty [1]:zwykłego wskaźnika, ze względu na poniższe koszty [1]: cykliczna struktura zbudowana z cykliczna struktura zbudowana z shared_ptrshared_ptr spowoduje wyciek przy spowoduje wyciek przy

destrukcji (któremu, kosztem dodatkowych operacji, można destrukcji (któremu, kosztem dodatkowych operacji, można przeciwdziałać, np. używając przeciwdziałać, np. używając weak_ptrweak_ptr),),

"shared ownership objects" zazwyczaj pozostają nieusunięte dłużej, niż "shared ownership objects" zazwyczaj pozostają nieusunięte dłużej, niż obiekty lokalne, powodując zwiększone zużycie zasobów,obiekty lokalne, powodując zwiększone zużycie zasobów,

mogą być kosztowne w środowisku wielowątkowym (ze względu na koszt mogą być kosztowne w środowisku wielowątkowym (ze względu na koszt unikania wyścigu danych dla licznika referencji),unikania wyścigu danych dla licznika referencji),

destruktor współdzielonego obiektu nie wykona się w przewidywalnym destruktor współdzielonego obiektu nie wykona się w przewidywalnym momencie, orazmomencie, oraz

łatwiej popełnić błąd w algorytmie/logice aktualizacji współdzielonego łatwiej popełnić błąd w algorytmie/logice aktualizacji współdzielonego obiektu, niż dla posiadanego jednokrotnie. obiektu, niż dla posiadanego jednokrotnie.

Inteligentne wskaźnikiInteligentne wskaźniki weak_ptrweak_ptr

pomocniczy wskaźnik do danych zarządzanych przez pomocniczy wskaźnik do danych zarządzanych przez shared_ptrshared_ptr;; nie posiada własności danych, przeznaczony dla nie posiada własności danych, przeznaczony dla danych posiadanych przez danych posiadanych przez shared_ptrshared_ptr

dostarcza testu czy wskazywana dana istniejedostarcza testu czy wskazywana dana istnieje posiada mechanizm blokowania/zapewnienia że na czas posiada mechanizm blokowania/zapewnienia że na czas

operacji wskazywana dana nie zostanie usuniętaoperacji wskazywana dana nie zostanie usunięta typowo nie niszczy wskazywanej danejtypowo nie niszczy wskazywanej danej

chyba że destrukcja została odłożona ze względu na blokowanie chyba że destrukcja została odłożona ze względu na blokowanie (ostatni shared_ptr do danej został usunięty gdy dana była (ostatni shared_ptr do danej został usunięty gdy dana była zablokowana), wtedy destrukcja po odblokowaniuzablokowana), wtedy destrukcja po odblokowaniu