PB161 Programování v jazyce C++ Přednáška 10

Podobné dokumenty
PB161 Programování v jazyce C++ Přednáška 10

PB přednáška (23. listopadu 2015)

Jazyk C++ I. Šablony

PB161 Programování v jazyce C++ Přednáška 7

Jazyk C++ II. Šablony a implementace

PB161 Programování v jazyce C++ Přednáška 9

PB161 Programování v jazyce C++ Přednáška 7

Jazyk C++ I. Šablony 2

Hrátky s funkcemi. PV173 Programování v C++11. Vladimír Štill, Jiří Weiser. Fakulta Informatiky, Masarykova Univerzita. 29.

Šablonové metaprogramování v C++ Miroslav Virius KSI FJFI ČVUT

PB161 Programování v jazyce C++ Přednáška 4

PB161 Programování v jazyce C++ Přednáška 3

Programování v C++ 1, 5. cvičení

PB161 Programování v jazyce C++ Přednáška 9

Programování v C++ 1, 1. cvičení

PB161 Programování v jazyce C++ Přednáška 9

PB161 Programování v jazyce C++ Přednáška 3

Cvičení z programování v C++ ZS 2016/2017 Přemysl Čech

PB161 Programování v jazyce C++ Přednáška 11

Programování se šablonami

Jazyk C++ I. Šablony 3

Pokročilé programování v jazyce C pro chemiky (C3220) Statické proměnné a metody, šablony v C++

PB161 Programování v jazyce C++ Přednáška 11

Funkční objekty v C++.

PROGRAMOVÁNÍ V C++ CVIČENÍ

Zpracoval:

Šablony, kontejnery a iterátory

PB161 Programování v jazyce C++ Přednáška 1

přetížení operátorů (o)

Jazyk C++ 1. Blok 3 Objektové typy jazyka C++ Třída. Studijní cíl. Doba nutná k nastudování. Průvodce studiem

Programování v C++ 1, 6. cvičení

PB161 Programování v jazyce C++ Přednáška 1

Vector datový kontejner v C++.

<surface name="pozadi" file="obrazky/pozadi/pozadi.png"/> ****************************************************************************

PB161 Programování v jazyce C++ Přednáška 4

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. October 17, 2016

Šablony funkcí a tříd (Templates) Genericita

PB161 Programování v jazyce C++ Přednáška 3

Dědění, polymorfismus

Jazyk C++ I. Polymorfismus

Programování v C++ 2, 4. cvičení

map, multimap - Asociativní pole v C++.

PB161 Programování v jazyce C++ Přednáška 8

Jazyk C++, některá rozšíření oproti C

přetížení operátorů (o)

Šablony, kontejnery a iterátory

Množina v C++ (set, multiset).

Programování v C++ 2, 8. cvičení

Výrazy, operace, příkazy

Konec a tak. PB173 Programování v C++11. Vladimír Štill, Jiří Weiser. Fakulta Informatiky, Masarykova Univerzita. 15.

Odvozené a strukturované typy dat

PROGRAMOVÁNÍ V C++ URČENO PRO VZDĚLÁVÁNÍ V AKREDITOVANÝCH STUDIJNÍCH PROGRAMECH ROSTISLAV FOJTÍK

Programování v C++ 1, 14. cvičení

PREPROCESOR POKRAČOVÁNÍ

Preprocesor. Karel Richta a kol. katedra počítačů FEL ČVUT v Praze. Karel Richta, Martin Hořeňovský, Aleš Hrabalík, 2016

Struktury, funkce, reference

Třídy a struktury v C++

PB161 Základy OOP. Tomáš Brukner

Výrazy, operace, příkazy

Standardní algoritmy vyhledávací.

Polymorfismus. Časová náročnost lekce: 3 hodiny Datum ukončení a splnění lekce: 30.března

Úvod do programovacích jazyků (Java)

PB161 Programování v jazyce C++ Přednáška 2

Řetězce. Karel Richta a kol. katedra počítačů FEL ČVUT v Praze. Karel Richta, Martin Hořeňovský, Aleš Hrabalík, 2016

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) Fakulta elektrotechniky a informatiky Katedra softwarových technologií

C++ objektově orientovaná nadstavba programovacího jazyka C

PB přednáška (26. října 2015)

PB161 Programování v jazyce C++ Přednáška 5

Domácí úkoly 2013/14

PB161 Programování v jazyce C++ Přednáška 6

Objektově orientované programování

Abstraktní třídy, polymorfní struktury

Data, výrazy, příkazy

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

C++ objektově orientovaná nadstavba programovacího jazyka C

Datové typy v Javě. Tomáš Pitner, upravil Marek Šabo

IUJCE Přednáška č. 11. další prvky globální proměnné, řízení viditelnosti proměnných, funkcí

Základy C++ I. Jan Hnilica Počítačové modelování 18

Iterátory v C++. int pole[20]; for (int *temp = pole, temp!= &pole[20]; temp++) { *temp = 0;

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Lekce 6 IMPLEMENTACE OPERAČNÍHO SYSTÉMU LINUX DO VÝUKY INFORMAČNÍCH TECHNOLOGIÍ JAZYK C

Dynamika objektů. Karel Richta a kol. katedra počítačů FEL ČVUT v Praze

Ukazatele, dynamická alokace

Úvod do programovacích jazyků (Java)

Rozsáhlé programy = projekty

Mělká a hluboká kopie

PŘETĚŽOVÁNÍ OPERÁTORŮ

Jazyk C# (seminář 3)

PB161 Programování v jazyce C++ Přednáška 6

Přetěžování operátorů

Standardní algoritmy v C++.

PB161 Programování v jazyce C++ Přednáška 6

Jazyk C++ I. Polymorfismus

Jazyk C# (seminář 6)

Programování v jazyce C a C++

PB přednáška (5. října 2015)

PB161 Programování v jazyce C++ Přednáška 2

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Jakub Čermák Microsoft Student Partner

Abstraktní datové typy

Transkript:

PB161 Programování v jazyce C++ Přednáška 10 Šablony Nikola Beneš 27. listopadu 2017 PB161 přednáška 10: šablony 27. listopadu 2017 1 / 33

Šablony PB161 přednáška 10: šablony 27. listopadu 2017 2 / 33

Motivace co nejmenší duplikace kódu stejný (podobný) kód pro různé typy kontejnery algoritmy možná řešení? makra void* OOP polymorfismus řešení v C++: šablony jiný druh polymorfismu generické programování metaprogramování PB161 přednáška 10: šablony 27. listopadu 2017 3 / 33

Šablony lepší makra generický kód, do nějž se později doplní typy tzv. instanciace a nejen typy instanciace vytvoření konkrétní entity ze šablony probíhá při kompilaci rozdíl proti generikům v některých jiných jazycích šablony mohou využívat funkce i třídy od C++11 i typové aliasy PB161 přednáška 10: šablony 27. listopadu 2017 4 / 33

Šablony Syntax template <seznam parametru> jeden nebo více parametrů C++11 variadické parametry (pokročilé) druhy parametrů typ: typename hodnota: celočíselný typ (int, bool, ), reference, ukazatel, výčtový typ (definovaný pomocí enum) šablona (pokročilé) parametr může mít implicitní hodnotu (pomocí =) místo typename možno použít class Příklad: template <typename T, size_t Size = 100, typename U = bool> PB161 přednáška 10: šablony 27. listopadu 2017 5 / 33

Šablony funkcí template <typename T> const T& mymax(const T& x, const T& y) { return x < y? y : x; int main() { int a, b; cin >> a >> b; cout << mymax<int>(a, b) << '\n'; cout << mymax(a, b) << '\n'; unsigned long c = 17; cout << mymax(a, c) << '\n'; // CHYBA cout << mymax<unsigned long>(a, c) << '\n'; PB161 přednáška 10: šablony 27. listopadu 2017 6 / 33

Šablony funkcí (pokr.) šablonové funkce se mohou přetěžovat template <typename T> const T& mymax(const T& x, const T& y, const T& z) { return mymax(mymax(x, y), z); template <typename T> const T& mymax(const vector<t>& vec) { return *max_element(vec.begin(), vec.end()); int main() { cout << mymax(2.0, 3.14) << '\n'; cout << mymax(2.0, 3.14, 42.0) << '\n'; vector<unsigned> v{ 10, 40, 20, 70, 30 ; cout << mymax(v) << '\n'; PB161 přednáška 10: šablony 27. listopadu 2017 7 / 33

Šablony funkcí (pokr.) funkce může být přetížená šablonovou i nešablonovou verzí nešablonová verze má přednost, pokud přesně typově sedí const char* mymax(const char* x, const char* y) { return strcmp(x,y) < 0? y : x; int main() { // zavolá se šablonová funkce mymax<int> cout << mymax(20, 70) << '\n'; // zavolá se nešablonová funkce mymax cout << mymax("ahoj", "hello") << '\n'; // co se zavolá teď? cout << mymax<const char*>("ahoj", "hello") << '\n'; // a co teď? cout << mymax<>("ahoj", "hello") << '\n'; PB161 přednáška 10: šablony 27. listopadu 2017 8 / 33

Šablony funkcí (pokr.) automatická dedukce šablonového typu jen jméno funkce funkce a prázdný seznam šablonových parametrů <> částečná automatická dedukce: vynechání některých parametrů template<typename T, typename U> T convert(const U& value) { return static_cast<t>(value); int main() { cout << convert(3.14) << '\n'; // CHYBA cout << convert<int, double>(3.14) << '\n'; // částečná dedukce: cout << convert<int>(3.14) << '\n'; PB161 přednáška 10: šablony 27. listopadu 2017 9 / 33

Šablony tříd Příklad: Jednoduchý kontejner template <typename T> class MyContainer { size_t size; unique_ptr<t> array; public: //... ; int main() { MyContainer<double> cont(10); //... PB161 přednáška 10: šablony 27. listopadu 2017 10 / 33

Šablony tříd (pokr.) u šablonových tříd není žádná automatická dedukce do C++14, od C++17 existují tzv. deduction guides důvod pro funkce jako std::make_pair template <typename T> class Foo { public: Foo(constT &); //... ; template <typename T> Foo<T> make_foo(const T& val) { return Foo<T>(val); int main() { auto foo = make_foo(1); PB161 přednáška 10: šablony 27. listopadu 2017 11 / 33

Šablony tříd (pokr.) uvnitř šablonových tříd mohou být šablonové metody template <typename T> class Foo { T value; public: Foo(const T& val) : value(val) { template <typename U> void print(const U& thing) { cout << value << " : " << thing << '\n'; ; int main() { Foo<double> foo(3.14); foo.print("example"); // 3.14 : example PB161 přednáška 10: šablony 27. listopadu 2017 12 / 33

Instanciace Kdy se vytvoří konkrétní instance šablony? během překladu pokud se v kódu objeví konkrétní použití prototyp nebo použití funkce použití třídy explicitní instanciace pro instanciaci je třeba vidět celou definici šablonové třídy/funkce důsledek buď inteligentní linker nebo šablonové třídy a funkce v hlavičkovém souboru realita: šablony musí být v hlavičkovém souboru PB161 přednáška 10: šablony 27. listopadu 2017 13 / 33

Instanciace (pokr.) Instance se vytváří jen pro to, co se skutečně použije. template<typename T> class X { T t; public: void f() { t.f(); void g() { t.g(); ; class A { public: void f() { ; int main() { X<A> x; x.f(); // takhle je to OK // x.g(); // po odkomentování se nezkompiluje Poznámka: Tohle nemusí platit pro virtuální metody. PB161 přednáška 10: šablony 27. listopadu 2017 14 / 33

Instanciace (pokr.) template<typename Container> void mysort(container& cont) { std::sort(cont.begin(), cont.end()); bude fungovat s libovolným typem, který má begin() a end() nebude fungovat s běžným Céčkovým polem (k zamyšlení) proto existují volné funkce std::begin() a std::end() šablony v C++ umožňují jistou formu duck-typingu PB161 přednáška 10: šablony 27. listopadu 2017 15 / 33

Kvíz https://kahoot.it PB161 přednáška 10: šablony 27. listopadu 2017 16 / 33

int main() { fun(0); fun("x"); fun<int>(1); PB161 přednáška 10: šablony 27. listopadu 2017 17 / 33 Kvíz (kód 1) #include <iostream> using std::cout; template<typename T> void fun(t t) { cout << "A" << t; void fun(int t) { cout << "B" << t;

Kvíz (kód 2) #include <iostream> using std::cout; template<typename T> class X { T t; public: void fun1() { t.f(); void fun2() { t.g(); ; class A { public: void f() { cout << "Af"; private: void g() { cout << "Ag"; ; int main() { X<A> x; // 1 X<int> y; // 2 x.fun1(); // 3 x.fun2(); // 4 PB161 přednáška 10: šablony 27. listopadu 2017 18 / 33

Typové aliasy v C++11 šablonové template<typename Element, typename Allocator> class BasicContainer { /*... */ ; template<typename Element> class StandardAllocator { /*... */ ; template<typename Element> using Container = BasicContainer<Element, StandardAllocator<Element>>; int main() { Container<double> c; // totéž, co BasicContainer<double, // StandardAllocator<double>> PB161 přednáška 10: šablony 27. listopadu 2017 19 / 33

Typové aliasy v C++11 (pokr.) nešablonové fungují jako typedef, jen s jinou (hezčí) syntaxí using VectorInt = std::vector<int>; using Number = int; using Function = void (*) (int, int); template <typename T> class Container { using valuetype1 = T; typedef T valuetype2; ; PB161 přednáška 10: šablony 27. listopadu 2017 20 / 33

Použití šablon funkční objekty jak fungují algoritmy ve standardní knihovně? funkci/funkční objekt berou jako šablonový argument template<typename Iterator, typename Function> void modify(iterator from, Iterator to, Function func) { for (auto it = from; it!= to; ++it) { *it = func(*it); PB161 přednáška 10: šablony 27. listopadu 2017 21 / 33

Specializace Úplná specializace šablony (pro třídy) speciální implementace pro konkrétní šablonové parametry uvozená deklarací template <> za názvem třídy konkrétní parametry v < > template <typename T> class X { /*... */ ; template <> class X<int> { /* speciální implementace pro int */ ; PB161 přednáška 10: šablony 27. listopadu 2017 22 / 33

Specializace (pokr.) kromě tříd se můžou úplně specializovat funkce (spíš nepoužívat) metody šablonových tříd statické atributy šablonových tříd a další (viz http://en.cppreference.com/w/cpp/language/ template_specialization) PB161 přednáška 10: šablony 27. listopadu 2017 23 / 33

Specializace (pokr.) specializace metody šablonové třídy template <typename T, typename U> class X { public: void foo() { std::cout << "unspecialised!\n"; ; template <> void X<int,double>::foo() { std::cout << "specialised!\n"; int main() { X<int, int> x; X<int, double> y; x.foo(); y.foo(); PB161 přednáška 10: šablony 27. listopadu 2017 24 / 33

Specializace (pokr.) Částečná specializace šablony jen pro třídy uvozená deklarací template <nespecializovane parametry> nespecializované parametry je pak možno použít v seznamu parametrů za názvem třídy PB161 přednáška 10: šablony 27. listopadu 2017 25 / 33

Specializace (pokr.) template <typename T, typename U> class X { /*... */ ; // 1 template <typename T> class X<T, double> { /*... */ ; // 2 template <typename T> class X<T, T> { /*... */ ; // 3 template <typename T> class X<int, T> { /*... */ ; // 4 X<double, char> x1; // použije se verze 1 X<char, double> x2; // použije se verze 2 X<char, char> x3; // použije se verze 3 X<int, char> x4; // použije se verze 4 X<int, int> x5; // CHYBA! není jasné, kterou verzi použít PB161 přednáška 10: šablony 27. listopadu 2017 26 / 33

Specializace (pokr.) doporučení pro specializace neměnit vnější chování příklad specializace ve standardní knihovně: std::vector<bool> spíš ukázka toho, jak nespecializovat zůstává v knihovně z důvodů zpětné kompatibility PB161 přednáška 10: šablony 27. listopadu 2017 27 / 33

Šablony nejen typové parametry šablon mohou být i (některé) hodnoty celočíselných typů (včetně bool, char) výčtových typů reference, ukazatele instance parametrů musí být konstantní výrazy Příklad použití ze standardní knihovny: template <typename T, std::size_t N> class array { T _array[n]; //... ; PB161 přednáška 10: šablony 27. listopadu 2017 28 / 33

Šablony nejen typové (pokr.) // klasický příklad: faktoriál při překladu template <unsigned N> struct Factorial { const static unsigned value = N * Factorial<N - 1>::value; ; template <> struct Factorial<0> { const static unsigned value = 1; ; int main() { // hodnota se spočítá při překladu, ne za běhu! return Factorial<5>::value; PB161 přednáška 10: šablony 27. listopadu 2017 29 / 33

Šablony nejen typové (pokr.) předání klasického Céčkového pole do funkce (včetně správné velikosti) template<typename T, std::size_t N> void print_array(const T (&array)[n]) { std::cout << N << " elements: "; std::cout << "{"; std::string separator = ""; for (const T& elem : array) { std::cout << separator << elem; separator = ", "; std::cout << "\n"; PB161 přednáška 10: šablony 27. listopadu 2017 30 / 33

Šablony jako parametry šablon parametrem šablony může být opět šablona template <typename Value, template <typename> class Container> class X { Container<Value> cont; //... ; // použití X<int, std::vector> x; // x obsahuje atribut cont typu std::vector<int> PB161 přednáška 10: šablony 27. listopadu 2017 31 / 33

Nápověda pro překladač typename template <typename T> class Container { public: using value_type = T; using ptr_type = T*; using size_type = unsigned int; size_type size() const; //... ; template <typename T> void do_something(container<t> & cont) { // nebude fungovat: Container<T>::size_type size = cont.size(); // je třeba napsat: typename Container<T>::size_type size = cont.size(); PB161 přednáška 10: šablony 27. listopadu 2017 32 / 33

Shrnutí Šablony velmi mocný nástroj zde jsme si ukázali jen základní použití mnohem více v PV264 generické funkce (metody) generické třídy nejen pro typy Instanciace šablon při překladu jen ty instance, které je nutné vyrobit jen ty části, které je nutné vyrobit (nemusí se týkat virtuálních funkcí) důsledek: šablony v hlavičkových souborech PB161 přednáška 10: šablony 27. listopadu 2017 33 / 33