27
KURS JĘZYKA C++ – WYKŁAD 13 (19.05.2014) Narzędzia programistyczne w bibliotece standardowej

Kurs języka C++ – wykład 13 (19.05.2014)

  • Upload
    tanaya

  • View
    54

  • Download
    0

Embed Size (px)

DESCRIPTION

Kurs języka C++ – wykład 13 (19.05.2014). Narzędzia programistyczne w bibliotece standardowej. Spis treści. Standardowa biblioteka wzorców STL Pary i tuple Sprytne wskaźniki Ograniczenia liczbowe Minimum i maksimum Zamiana zawartości obiektów Operatory porównywania Współczynniki - PowerPoint PPT Presentation

Citation preview

Page 1: Kurs języka C++  – wykład 13 (19.05.2014)

KURS JĘZYKA C++ – WYKŁAD 13 (19.05.2014)

Narzędzia programistyczne w bibliotece standardowej

Page 2: Kurs języka C++  – wykład 13 (19.05.2014)

SPIS TREŚCI

Standardowa biblioteka wzorców STL Pary i tuple Sprytne wskaźniki Ograniczenia liczbowe Minimum i maksimum Zamiana zawartości obiektów Operatory porównywania Współczynniki Pomiar czasu Funkcje lambda

Page 3: Kurs języka C++  – wykład 13 (19.05.2014)

STL

STL (ang. Standard Template Library) to standardowa biblioteka wzorców w C++.

Wszystkie składniki STL są wzorcami. STL jest rdzeniem biblioteki standardowej C++. Wszystkie identyfikatory w bibliotece standardowej C++

zdefiniowane są w przestrzeni nazw std. Zaleta STL – mnóstwo gotowych szablonów klas

pozwalających programować na wyższym poziomie abstrakcji.

Wada STL – brak oczywistości (koniecznie czytaj dokumentację)

Page 4: Kurs języka C++  – wykład 13 (19.05.2014)

STL

Biblioteka STL składa się z kilku modułów: strumienie we/wy, kontenery, iteratory, algorytmy, obiekty funkcyjne, łańcuchy, wyrażenia regularne, wielowątkowość i przetwarzanie współbieżne, internacjonalizacja, klasy narzędziowe.

Page 5: Kurs języka C++  – wykład 13 (19.05.2014)

PARY

Szablon struktury pair<> (zdefiniowany w <utility>) umożliwia potraktowanie dwóch wartości jako pojedynczego elementu.

Para posiada dwa pola: first i second. Para posiada konstruktor dwuargumentowy oraz domyślny i kopiujący. Pary można porównywać (operatory == i <). Istnieje szablon funkcji make_pair() do tworzenia pary (typy danych są

rozpoznawane przez kompilator po typach argumentów). Przykłady:void f (std::pair<int, const char *>);void g (std::pair<const int, std::string>);…std::pair<int, const char *> p(44,”witaj”);f(p); // wywołuje domyślny konstruktor kopiującyg(p); // wywołuje konstruktor wzorcowyg(std::make_pair(44,”witaj”)); // przekazuje dwie // wartości jako parę z wykorzystaniem konwersji // typów

Pary są wykorzystywane w kontenerach map i multimap.

Page 6: Kurs języka C++  – wykład 13 (19.05.2014)

PARY – PRZYKŁADY

void f(std::pair<int, const char*>);

void g(std::pair<const int, std::string>);

...

std::pair<int, const char*> p(46,"hello");

f(p); // OK:

// calls implicitly generated copy constructor

g(p); // OK:

// calls template constructor

Page 7: Kurs języka C++  – wykład 13 (19.05.2014)

TUPLE

W C++11 zdefiniowano tuple do przechowywania wielu wartości a nie tylko dwóch (szablon tuple<> jest analogią do szblony pary pair<>).

Tupla posiada wiele ponumerowanych pól, do których dostęp mamy za pomocą metody get<i>.

Tupla posiada konstruktor wieloargumentowy oraz domyślny i kopiujący. Tuple można porównywać za pomocą operatorów porównań (porównywanie

leksykograficzne). Istnieje szablon funkcji make_tuple() do tworzenia tupli (typy danych są

rozpoznawane przez kompilator po typach argumentów). Istnieje szablon funkcji tie() do tworzenia tupli z referencjami (jako

argumenty podaje się zmienne). Szablon tuple_size<tupletype>::value służy do podania liczby

elementów w tupli. Szablon tuple_element<idx,tupletype>::type służy do podania

typu elementu o indeksie idx w tupli.

Page 8: Kurs języka C++  – wykład 13 (19.05.2014)

TUPLE – PRZYKŁADY

// create a four-element tuple

// - elements are initialized with default value

tuple<string,int,int,complex<double>> t;

// create and initialize a tuple explicitly

tuple<int,float,string> t1(41,6.3,"nico");

// ‘‘iterate’’ over elements:

cout << get<0>(t1) << " ";

cout << get<1>(t1) << " ";

cout << get<2>(t1) << " ";

cout << endl;

Page 9: Kurs języka C++  – wykład 13 (19.05.2014)

TUPLE – PRZYKŁADY

// create tuple with make_tuple()

// - auto declares t2 with type of right-hand side

auto t2 = make_tuple(22,44,"nico");

// assign second value in t2 to t1

get<1>(t1) = get<1>(t2);

// comparison and assignment

// - including type conversion

if (t1 < t2) { // compares value for value

t1 = t2; // OK, assigns value for value

}

Page 10: Kurs języka C++  – wykład 13 (19.05.2014)

SPRYTNE WSKAŹNIKI Sprytne wskaźniki są zdefiniowane w pliku nagłówkowym <memory>. Sprytne wskaźniki maksymalnie naśladują zwykłe wskaźniki. Sprytne wskaźniki wspierają technikę zdobywania zasobów poprzez

inicjalizację. Wskaźnik shared_pointer<> jest wskaźnikiem ze zliczaniem referencji –

współdzielony wskaźnik automatycznie niszczy swoją zawartość, jeśli nie ma już współdzielonych wskaźników odnoszących się do obiektu początkowo tworzonego dla współdzielonego wskaźnika.

Słaby wskaźnik weak_ptr<> jest referencją do wskaźnika shared_ptr<>, która może określać, czy wskaźnik shared_ptr<> był kasowany czy też nie – sam weak_ptr<> nie ma na celu zachowywanie się jak zwykły wskaźnik C++; po prostu jest obiektem i dostęp do faktycznego wskaźnika wymaga stworzenia obiektu shared_ptr<>.

Wskaźnik unique_ptr<> jest zamiennikiem przestarzałego auto_ptr<> – ma wszystkie możliwości auto_ptr<> z wyjątkiem niebezpiecznego niejawnego przenoszenia z l-wartości; wskaźnik unique_ptr<> może być stosowany z kontenerami C++11 uwzględniającymi przenoszenie.

Page 11: Kurs języka C++  – wykład 13 (19.05.2014)

OGRANICZENIA LICZBOWE Typy numeryczne posiadają ograniczenia zależne od platformy i

są zdefiniowane w szablonie numeric_limits<> (zdefiniowany w <limits>, stałe preprocesora są nadal dostępne w <climits> i <cfloat>).

Wybrane składowe statyczne szablonu numeric_limits<>: is_signed, is_integer, is_exact, is_bounded, is_modulo, has_infinity, has_quiet_NaN, min(), max(), epsilon().

Przykłady:numeric_limits<char>::is_signed;numeric_limits<short>::is_modulo;numeric_limits<long>::max();numeric_limits<float>::min();numeric_limits<double>::epsilon();

Page 12: Kurs języka C++  – wykład 13 (19.05.2014)

MINIMUM I MAKSIMUM Obliczanie wartości minimalnej oraz maksymalnej:template <class T>inline const T& min (const T &a, const T &b) { return b<a ? b : a; }template <class T>inline const T& max (const T &a, const T &b) { return a<b ? b : a; }

Istnieją też wersje tych szablonów z komparatorami (funkcja lub obiekt funkcyjny):template <class T, class C>inline const T& min (const T &a, const T &b, C comp) { return comp(b,a) ? b : a; }template <class T>inline const T& max (const T &a, const T &b, C comp) { return comp(a,b) ? b : a; }

Page 13: Kurs języka C++  – wykład 13 (19.05.2014)

MINIMUM I MAKSIMUM Przykład 1:bool int_ptr_less (int *p, int *q) { return *p<*q; }…int x = 33, y = 44;int *px = &x, *py = &y;int *pmax = std::max(px,py,int_ptr_less);

Przykład 2:int i;long l;…l = max(i,l); // BŁĄD // niezgodne typy argumentówl = std::max<long>(i,l); // OK

Page 14: Kurs języka C++  – wykład 13 (19.05.2014)

MINIMUM I MAKSIMUM Funkcja minmax()zwraca parę elementów pair<>, gdzie pierwszy element

jest minimum a drugi maksimum. Argumentem funkcji minmax()są dwa elementy albo lista elementów;

ostatnim argumentem może być metoda porównująca. Przykład:bool int_ptr_less (int* a, int* b) { return *a < *b; }int x = 17, *px = &x;int y = 42, *py = &y;int z = 33, *pz = &z;...std::pair<int*, int*> extremes = std::minmax ({px, py, pz}, int_ptr_less);// auto extremes =// std::minmax ({px, py, pz}, // [](int*a, int*b) { return *a < *b; });

Page 15: Kurs języka C++  – wykład 13 (19.05.2014)

ZAMIANA ZAWARTOŚCI OBIEKTÓW

Zamiana dwóch wartości:template <typename T>inline void swap (T &a, T &b) { T tmp(a); a = b; b = tmp; }

Można też zamieniać ze sobą tablice o określonej liczbie elementów:template <typename T, size_t N>void swap (T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b)));

Przykład:int x = 33, y = 44;…std::swap(x,y);

Page 16: Kurs języka C++  – wykład 13 (19.05.2014)

OPERATORY PORÓWNYWANIA

Cztery funkcje szablonowe (zdefiniowane w <utility>) na podstawie operatorów == i < definiują operatory porównań !=, <=, >= i >.

Funkcje te są umieszczone w przestrzeni nazw std::rel_ops. Przykład:class X { …public: bool operator== (const X &x) const throw(); bool operator< (const X &x) const throw(); …};…void foo () { using namespace std::rel_ops; X x1, x2; … if (x1!=x2) { … } …}

Page 17: Kurs języka C++  – wykład 13 (19.05.2014)

WSPÓŁCZYNNIKI W pliku nagłówkowym <ratio> jest zdefiniowany szablon

do tworzenia współczynników. Definicja tego szablonu przypomina liczbę wymierną:template <intmax_t N, intmax_t D = 1>class ratio {public: typedef ratio<num,den> type; static constexpr intmax_t num; static constexpr intmax_t den;//…};

Licznik num i mianownik den są automatycznie redukowane do minimalnych wartości (mianownik będzie dodatni).

Page 18: Kurs języka C++  – wykład 13 (19.05.2014)

WSPÓŁCZYNNIKI – PRZYKŁADY

typedef ratio<25,15> FiveThirds;

cout << FiveThirds::num << "/"

<< FiveThirds::den << endl;

// 5/3

ratio<42,42> one;

cout << one.num << "/" << one.den << endl;

// 1/1

ratio<0> zero;

cout << zero.num << "/" << zero.den << endl;

// 0/1

typedef ratio<7,-3> Neg;

cout << Neg::num << "/" << Neg::den << endl;

// -7/3

Page 19: Kurs języka C++  – wykład 13 (19.05.2014)

WSPÓŁCZYNNIKI

Obliczenia na współczynnikach można wykonywać w trakcie kompilacji za pomocą następujących szablonów: ratio_add, ratio_subtract, ratio_multiply i ratio_divide (operacje arytmetyczne) oraz ratio_equal, ratio_not_equal, ratio_less, ratio_less_equal, ratio_greater i ratio_greater_equal (porównania).

Przykład:ratio_add<ratio<2,7>,ratio<2,6>>::typeratio_equal<ratio<5,3>,ratio<25,15>>::value

Istnieje też wiele predefiniowanych jednostek ratio<>: pico, nano, micro, milli, centi, deci, deca, hecto, kilo, mega, giga, tera…

Page 20: Kurs języka C++  – wykład 13 (19.05.2014)

POMIAR CZASU

Biblioteka standardowa wprowadza narzędzia pomocne do pomiaru czasu – są one zdefiniowane w pliku nagłówkowym <chrono> w przestrzeni nazw std::chrono.

Podstawowe pojęcia: punkt czasowy (ang. timepoint), przedział czasowy (ang. duration), epoka – punkt bieżący zegara (ang. epoch).

Page 21: Kurs języka C++  – wykład 13 (19.05.2014)

POMIAR CZASU Przedział czasowy reprezentowany przez szablon std::chrono::duration<> jest liczbą określonych jednostek czasowych (mierzonych w sekundach).

Przykłady:std::chrono::duration<int> twentySeconds(20);std::chrono::duration<double,std::ratio<60>> halfAMinute(0.5);std::chrono::duration<long,std::ratio<1,1000>> oneMillisecond(1);

W bibliotece standardowej zdefiniowano następujące typy przedziałów czasowych: nanoseconds, microseconds, milliseconds, seconds, minutes i hours.

Przykłady:std::chrono::seconds twentySeconds(20);std::chrono::hours aDay(24);

Page 22: Kurs języka C++  – wykład 13 (19.05.2014)

POMIAR CZASU

Przedziały czasowe możemy porównywać, dodawać, odejmować, mnożyć i dzielić przez współczynniki oraz inkrementować i dekrementować o określoną jednostkę.

Przykład:chrono::duration<int,ratio<1,3>> d1(1); // 1/3 sekundychrono::duration<int,ratio<1,5>> d2(1); // 1/5 sekundyd1 + d2 /* 8 jednostek z 1/15 sekundy */d1 < d2 /* false */

Page 23: Kurs języka C++  – wykład 13 (19.05.2014)

POMIAR CZASU Zegar definiuje epokę i długość tyknięcia zegara. W bibliotece standardowej zdefiniowane są trzy zegary: system_clock (z funkcjami to_time_t() oraz from_time_t()), steady_clock (nigdy nie korygowany) i high_resolution_clock (dokładny zegar systemowy).

Bieżący czas można uzyskać za pomocą metody now():auto system_start = chrono::system_clock::now();

Sprawdzenie czy upłynęła co najmniej minuta do startu:if (system_clock::now() > system_start + minutes(1))

Page 24: Kurs języka C++  – wykład 13 (19.05.2014)

POMIAR CZASU Punkt czasowy jest reprezentowany przez obiekt time_point. Pomiaru czasu można dokonać za pomocą punktów czasowych:auto t = steady_clock::now();// ... do something ...auto d = steady_clock::now()−t;

Konwersja punktu czasowego do postaci kalendarzowej: std::string asString (const std::chrono::system_clock::time_point &tp) { // convert to system time: std::time_t t = std::chrono::system_clock::to_time_t(tp); std::string ts = std::ctime(&t); // convert to calendar time ts.resize(ts.size()-1); // skip trailing newline return ts;}

Page 25: Kurs języka C++  – wykład 13 (19.05.2014)

FUNKCJE LAMBDA

Programista często chciałby zdefiniować predykatowe funkcje w pobliżu wywołań takich funkcji, jak na przykład pochodzących ze standardowej biblioteki <algorithm> (szczególnie sort i find) – oczywistym rozwiązaniem jest zdefiniowanie w takim miejscu funkcji lambda (określanej też jako lambda-wyrażenie).

Funkcje lambda to anonimowe obiekty funkcyjne. Główne zastosowanie funkcji lambda to ich użycie jako

argumentu sterującego obliczeniami w innych funkcjach. Przykład:[](int x, int y) { return x + y; }

Page 26: Kurs języka C++  – wykład 13 (19.05.2014)

FUNKCJE LAMBDA

Funkcja lambda określa typ zwracanego wyniku za pomocą frazy -> TYP.

Przykład:[](int x, int y) -> int { int z = x * x; return z + y + 1; }

Jeśli ciało funkcji lambda składa się z jednej instrukcji return, to typ zwracanego wyniku będzie wydedukowany za pomocą decltype().

Przykład:[](int x, int y) // -> decltype(x*x+y+1) { return x * x + y + 1; }

Page 27: Kurs języka C++  – wykład 13 (19.05.2014)

FUNKCJE LAMBDA