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

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

Jazyk C++ I. Šablony 2

Jazyk C++ I. Šablony

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

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

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

Jazyk C++ II. Šablony a implementace

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

Výčtový typ strana 67

Ukazka knihy z internetoveho knihkupectvi

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

GENERICKÉ PROGRAMOVÁNÍ: CÍLE A MOŽNOSTI IMPLEMENTACE

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

Programování v jazyce C pro chemiky (C2160) 3. Příkaz switch, příkaz cyklu for, operátory ++ a --, pole

Úvod do programovacích jazyků (Java)

Úvod do programování - Java. Cvičení č.4

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

Bitové operátory a bitová pole. Úvod do programování 2 Tomáš Kühr

Algoritmizace a programování

Algoritmizace a programování

PROGRAMOVACÍ JAZYKY A PŘEKLADAČE REALIZACE PŘEKLADAČE I

Opakování programování

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

MATURITNÍ OTÁZKY ELEKTROTECHNIKA - POČÍTAČOVÉ SYSTÉMY 2003/2004 PROGRAMOVÉ VYBAVENÍ POČÍTAČŮ

Základní pojmy. Úvod do programování. Základní pojmy. Zápis algoritmu. Výraz. Základní pojmy

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

Jazyky C a C++ kompletní průvodce 2., aktualizované vydání. Miroslav Virius

Zápis programu v jazyce C#

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

Jazyk C++ I. Šablony 3

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

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

Zobrazování 2D Nadpis křivek 2 Nadpis 3

Objektově orientované programování

Úvod do programování. Lekce 3

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

Střední škola pedagogická, hotelnictví a služeb, Litoměříce, příspěvková organizace

Generické programování

IUJCE 07/08 Přednáška č. 1

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

Rekurze. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 12.

Příkazy preprocesoru - Před překladem kódu překladačem mu předpřipraví kód preprocesor - Preprocesor vypouští nadbytečné (prázdné) mezery a řádky -

Programovací jazyk C++ Hodina 1

PREPROCESOR POKRAČOVÁNÍ

1. Téma 03 - Rozhodování

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

Poslední nenulová číslice faktoriálu

Funkce pokročilé možnosti. Úvod do programování 2 Tomáš Kühr

Zpracoval:

Úvod do programovacích jazyků (Java)

for (i = 0, j = 5; i < 10; i++) { // tělo cyklu }

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

Řídicí struktury. alg3 1

Programování se šablonami

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

1. Programování proti rozhraní

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

Abstraktní třídy, polymorfní struktury

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

Obsah. Úvod 11 Základy programování 11 Objektový přístup 11 Procvičování 11 Zvláštní odstavce 12 Zpětná vazba od čtenářů 12 Errata 13

Rozsáhlé programy = projekty

Jazyk C++ I. Polymorfismus

Strukturované typy a ukazatele. Úvod do programování 1 Tomáš Kühr

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 12.

5 Přehled operátorů, příkazy, přetypování

Programovací jazyk Java

Matematika v programovacích

Algoritmizace a programování

VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu

Základy algoritmizace a programování

Data, výrazy, příkazy

Třídy a struktury v C++

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

Standardní algoritmy vyhledávací.

O autorovi O odborném korektorovi Úvod 17 Vývoj jazyka Java Java SE 8 Struktura této knihy Předchozí zkušenosti s programováním nejsou potřebné

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

Výrazy, operace, příkazy

Výrazy a operátory. Operátory Unární - unární a unární + Např.: a +b

Kritéria hodnocení praktické maturitní zkoušky z databázových systémů

Dědění, polymorfismus

Úvod do programování. Lekce 1

NPRG031 Programování II --- 2/2 Z, Zk

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

Programování v jazyce C a C++

Logické operace. Datový typ bool. Relační operátory. Logické operátory. IAJCE Přednáška č. 3. může nabýt hodnot: o true o false

Jazyk C pro pokročilé

Operační systémy. Cvičení 4: Programování v C pod Unixem

Standardní algoritmy v C++.

VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu

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

Základy algoritmizace a programování

Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody

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

11. Přehled prog. jazyků

Hornerovo schéma. je algoritmus výpočtu hodnoty polynomu P(x) v bodě x 0. eliminuje výpočet i-té mocniny převodem na postupné násobení.

Jazyk C# (seminář 6)

PROGRAMOVÁNÍ V JAZYCE C V PŘÍKLADECH 11 Dynamické datové struktury 11.1 Spojové struktury Příklad PROG_

Kritéria hodnocení praktické maturitní zkoušky z databázových systémů

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

Začínáme vážně programovat. Řídící struktury Přetypování Vstupně výstupní operace Vlastní tvorba programů

Transkript:

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

Šablonové (generické) metaprogramování Šablona v C++, genericita v jiných jazycích Výpočetní úplnost Problémy Příklad Porovnání s klasickým výpočtem 2

C++ vs. Java 5, C# 2 Podstatný rozdíl mezi C++ na jedné straně a Javou a C# na druhé straně: C++: Parametrizovaná množina objektových typů a volných funkcí, instance se definují v době překladu a představují různé typy či funkce C#, Java: existuje jen jeden typ či metoda, kontroly použití v době překladu, přetypování za běhu 3

Šablona v C++ Většinou chápána jako nástroj pro generování parametrizované množiny tříd nebo volných funkcí Tak opravdu vznikla Návrh STL si vynutil rozšíření možností Parciální a úplné specializace Vnořené šablony Přetěžování šablon volných funkcí Atd. Nástroj pro programování překladače 4

První metaprogram E. Unruh, 1995: Program, který nelze přeložit, ale v chybových hlášeních vypíše prvních n prvočísel Metaprogramování jako směr Standardní knihovna C++ je založena mj. na některých metaprogramových konstrukcích 5

Parciální a úplná specializace // Primární šablona template<typename T> class vektor { // Nějaká definice }; // Parciální specializace pro určitou // skupinu typů template<typename T> class vektor<t*> { // Nějaká jiná definice }; // Úplná specializace template<> class vector<bool> { /*...*/ } 6

Nejjednodušší příklad Analogie makra assert() v době překladu // Primární šablona není definována template<bool b> class Assert; // Specializace pro true template<> class Assert<true> {}; // Užití: Assert< (N > O) > a; 7

Výpočetní úplnost Zobrazení typů a čísel na objektové typy template <int N> struct int2typ { enum {vysledek = N}; }; template <class T> struct typ2typ { typedef T typ; }; typ2typ<int>::typ x = int2typ<5>::vysledek; // int x = 5; 8

Výpočetní úplnost: Podmínka template<bool, class, class> class IfThenElse; template<typename T1, typename T2> struct IfThenElse<true, T1, T2> { typedef T1 Typ; }; template<typename T1, typename T2> struct IfThenElse<false, T1, T2> { typedef T2 Typ; }; IfThenElse<n==2,int,double>::Typ x = 3; 9

Výpočetní úplnost: Přepínač template<int N,class T1,class T2,class T3> struct Switch { typedef T3 typ; }; // Alternativa default: template<class T1, class T2, class T3> struct Switch<0, T1, T2, T3> { typedef T1 typ; }; // Pro N == 0 atd. 10

Výpočetní úplnost: Cyklus Náhrada rekurzivními parciálními specializacemi Ukončení cyklu explicitní specializací Výsledek: v podstatě funkcionální programování (připomíná např. LISP) Rekurzivní generování typů Pokud typ neobsahuje než výčtové typy a typedef, nezpůsobí generování žádného kódu 11

Příklad cyklu: Výpočet faktoriálu template<int n> // Primární šablona struct fakt // pro n > 0 { enum{ vysledek=n*fakt<n-1>::vysledek }; }; template<> // Specializace pro n == 0 struct fakt<0> // ukončuje rekurzi { enum{ vysledek=1 }; }; int x = fakt<5>::vysledek; 12

Shrnutí: Výpočetní úplnost Aparát šablon umožňuje: používat celočíselné parametry šablon jako stavové proměnné, implementovat rozhodování prostřednictvím specializace šablon nebo pomocí podmíněného operátoru?:, implementovat cykly pomocí rekurzivních explicitních nebo parciálních specializací šablon, používat celočíselnou aritmetiku 13

Problémy Omezení na celočíselnou aritmetiku Překladač může omezit hloubku rekurze při generování instancí šablon na pouhých 17 (!) Obtížné ladění Překladače nevyhovující standardu 14

Využití idejí ŠM pro optimalizaci: Výpočet skalárního součinu Jde o výpočet a[0]*b[0] + a[1]*b[1] +... + a[n-1]*b[n-1] (*) Tradiční způsob: template<typename T> inline T SkSoucin(int n, T* a, T* b) { T r = 0; for(int i = 0; i < n; ++i) r += a[i]*b[i]; return r; } Překladače optimalizují na velký počet opakování cyklu, při n == 2 nebo 3 je to kontraproduktivní. Rozepsat (*) je nejvýhodnější, ale 15

Pomocí metaprogramu (1) // Primární šablona // pro výpočet skalárního součinu template<int n, typename T> struct SkalSoucin { static T hodnota(t* a, T* b) { return *a * *b + SkalSoucin<n-1, T>::hodnota(a+1, b+1); } }; 16

Metaprogram (2) // Parciální specializace pro n == 1 // ukončuje rekurzi template<typename T> struct SkalSoucin<1, T> { static T hodnota(t* a, T* b) { return *a * *b ; } }; 17

Metaprogram (3) // Neintuitivní zápis C = SkalSoucin<3, double>::hodnota(a, b); // lze obalit pomocnou funkcí template<int n, typename T> inline T skal_souc(t *a, T *b) { return SkalSoucin<n, T>::hodnota(a, b); } 18

Porovnání int main() { // volatile volatile double A[3] = {1,2,3}; // zabraňuje volatile double B[3] = {4,5,6}; // optimalizacím double C; // Přípravné operace _timeb T1, T2; _ftime(&t1); // Začátek měření času for(int i = 0; i < N; ++i) C = SkSoucin(3, A, B); _ftime(&t2); // Konec měření času //... Výpočet rozdílu časů a výstup výsledku //... Totéž pro skal_souc<3>(a, B) // a pro rozepsaný skalární součin } 19

Výsledky (v sekundách) const int N=1000000000 // Počet násobených polí 10 9 BCX GNU Intel MSVC Klasicky 72,3 83,5 Metaprogram 10,8 52,3 Rozepsaný součin 3,0 4,1 42,0 (0,6) * 15,6 2050 (0,35) * 4,1 2049 (0,16) * 5,3 * Bez modifikátoru volatile 20

Děkuji za pozornost. 21