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

Podobne dokumenty