Templatemetaprogrammierung in C++ FlorianJW



Ähnliche Dokumente
Einführung in die Programmierung (EPR)

Einführung in die Programmierung

Einführung in die C++ Programmierung für Ingenieure

Klausur in Programmieren

Gebundene Typparameter

Einführung in die Programmierung

2. Semester, 2. Prüfung, Lösung

Zählen von Objekten einer bestimmten Klasse

Modellierung und Programmierung 1

Objektbasierte Entwicklung

Objektorientierte Programmierung mit C++ Vector und List

Informatik I (D-MAVT)

Test-Driven Design: Ein einfaches Beispiel

Ziel, Inhalt. Programmieren in C++ Wir lernen wie man Funktionen oder Klassen einmal schreibt, so dass sie für verschiedene Datentypen verwendbar sind

Funktionen Häufig müssen bestimmte Operationen in einem Programm mehrmals ausgeführt werden. Schlechte Lösung: Gute Lösung:

Prinzipien Objektorientierter Programmierung

Hochschule Darmstadt Informatik-Praktikum (INF 1) WS 2015/2016 Wirtschaftsingenieur Bachelor 5. Aufgabe Datenstruktur, Dateieingabe und -ausgabe

Scala kann auch faul sein

Pass by Value Pass by Reference Defaults, Overloading, variable Parameteranzahl

Felder, Rückblick Mehrdimensionale Felder. Programmieren in C

Informatik Grundlagen, WS04, Seminar 13

Unterprogramme. Funktionen. Bedeutung von Funktionen in C++ Definition einer Funktion. Definition einer Prozedur

Übung 1 mit C# 6.0 MATTHIAS RONCORONI

Objektorientierte Programmierung

Vorkurs C++ Programmierung

1. Übung zu "Numerik partieller Differentialgleichungen"

Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung: Lösungsvorschlag

Einführung in die C-Programmierung

4. Lernen von Entscheidungsbäumen. Klassifikation mit Entscheidungsbäumen. Entscheidungsbaum

WPF Steuerelemente Listbox, ComboBox, ListView,

Deklarationen in C. Prof. Dr. Margarita Esponda

Einführung in die Java- Programmierung

In vergleichsbasierten Suchbäumen wird nicht in Schlüssel hineingeschaut.

Nun kommt etwas wirklich Abgefahrenes. Wenn Sie zu den Leuten gehören, denen Logikrätsel keinen

Projektverwaltung Problem Lösung: Modulare Programmierung

Operationalisierbare Qualitätskriterien für die Programmierung mit Erfahrungen aus PRÜ1 und PRÜ2

Verhindert, dass eine Methode überschrieben wird. public final int holekontostand() {...} public final class Girokonto extends Konto {...

Klausur in Programmieren

Propädeutikum. Dipl.-Inf. Frank Güttler

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen

Das Typsystem von Scala. L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala

Ein Blick voraus. des Autors von C++: Bjarne Stroustrup Conrad Kobsch

Programmieren in C. Macros, Funktionen und modulare Programmstruktur. Prof. Dr. Nikolaus Wulff

Javadoc. Programmiermethodik. Eva Zangerle Universität Innsbruck

Hochschule München, FK 03 FA SS Ingenieurinformatik

Java: Vererbung. Teil 3: super()

Wiederholung und Vertiefung. Programmieren in C. Pointer und so... thoto. /dev/tal e.v. 6. April 2013 (Version vom 11. April 2013) Programmieren in C

5. Tutorium zu Programmieren

Hello World. Javakurs 2014, 1. Vorlesung. Sebastian Schuck. basierend auf der Vorlage von Arne Kappen. wiki.freitagsrunde.org. 3.

Einführung in die Java- Programmierung

Datentypen: Enum, Array, Struct, Union

How To: Wie entwickle ich mit SharpDevelop Anwendungen für die PocketPC-Platform

Systeme 1. Kapitel 6. Nebenläufigkeit und wechselseitiger Ausschluss

C-Probeklausur (Informatik 1; Umfang: C, Teil 1; SS07)

Einfache Arrays. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Angewandte Mathematik und Programmierung

Einführung in die Programmierung für Wirtschaftsinformatik

Allgemeines. Verschiedene Sprachkonzepte C-Sprachfamilie C-ähnliche Programmiersprachen Allgemeines zu C. #include <stdio.h>

Delegatesund Ereignisse

Benutzung der LS-Miniscanner

C++11 ist da. Und jetzt?

Zur drittletzten Zeile scrollen

Informatik Repetitorium SS Volker Jaedicke

Einführung in die Programmierung

C/C++-Programmierung

Erweiterung der Aufgabe. Die Notenberechnung soll nicht nur für einen Schüler, sondern für bis zu 35 Schüler gehen:

Programmieren in Haskell Einführung

Melde- und Veröffentlichungsplattform Portal (MVP Portal) Hochladen einer XML-Datei

Grundlagen der Programmierung Prof. H. Mössenböck. 14. Schrittweise Verfeinerung

Erwin Grüner

C++ Tutorial: Timer 1

Kontrollstrukturen und Funktionen in C

Einführung in. Logische Schaltungen

Zusammengesetzte Datentypen -- Arrays und Strukturen

Programmiervorkurs SS 2011 Technische Universität Darmstadt Jan Hendrik Burdinski, Felix Kerger

Sichere Anleitung Zertifikate / Schlüssel für Kunden der Sparkasse Germersheim-Kandel. Sichere . der

Objektorientierte Programmierung für Anfänger am Beispiel PHP

Praktikum zu Einführung in die Informatik für LogWiIngs und WiMas Wintersemester 2015/16. Vorbereitende Aufgaben

Klausur in Programmieren

Einführung in wxwidgets & wxdev-c++

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 16

Teaser-Bilder erstellen mit GIMP. Bildbearbeitung mit GIMP 1

5 DATEN Variablen. Variablen können beliebige Werte zugewiesen und im Gegensatz zu

Programmierung in C. Grundlagen. Stefan Kallerhoff

Daniel Warneke Ein Vortrag im Rahmen des Proseminars Software Pioneers

Um das Versenden von Anhängen an s zu ermöglichen, wurde der Assistent für die Kommunikation leicht überarbeitet und wo nötig verbessert.

Computeranwendung und Programmierung (CuP)

Arbeiten mit UMLed und Delphi

10 Erweiterung und Portierung

C/C++ Programmierung

Pragmatik von Programmiersprachen

FH-SY Chapter Version 3 - FH-SY.NET - FAQ -

12. Vererbung. Prof. Dr. Markus Gross Informatik I für D-ITET (WS 03/04)

Objektorientierte Programmierung

Wie Sie mit Mastern arbeiten

Programmierkurs Java

Java Kurs für Anfänger Einheit 5 Methoden

Java-Schulung Grundlagen

Diplomarbeit Antrittsvortrag

Transkript:

Templatemetaprogrammierung in C++ FlorianJW

Wiederholung Verwendung #i n c l u de <v e c t o r > #i n c l u de <a l g o r i t h m > #i n c l u de <s t r i n g > i n t main ( ) { s t d : : v e c t o r <int > vec { 1, 2, 3 ; using s t d : : s t r i n g ; auto s t r = s t d : : min ( s t r i n g { foo, s t r i n g { bar ) ;

Wiederholung allgemeine Funktionstemplates // yes, t h i s i s e x t r e m l y s i m p l i f i e d : template<typename T> T max(t arg1, T arg2 ) { return ( arg1 > arg2 )? arg1 : arg2 ;

Wiederholung spezialisierte Funktionstemplates #i n c l u de <c s t d l i b > template<> char max( char arg1, char arg2 ) { return strcmp ( arg1, arg2 ) < 0? arg2 : arg1 ;

Wiederholung Klassentemplates und integrale Templateargumente template<typename T, s t d : : s i z e t Tsize > c l a s s my array { T data [ T s i z e ] ; p u b l i c : my array ( ) = d e f a u l t ; T& operator [ ] ( s i z e t i n d e x ){ return data [ i n d e x ] ; //... ;

Wiederholung teilweise Spezialisierung von Klassentemplates template<s t d : : s i z e t Tsize > c l a s s my array <bool, Tsize >{ // e x p e r i e n c e with s t d : : v e c t o r <bool > // showed t h a t t h i s i s a s t u p i d i d e a : i n t data [ ( T s i z e +1) / ( s i z e o f ( i n t ) CHAR BIT ) ] ; //... ; Nur für Klassentemplates. Für Funktionstemplates lässt sich ähnliches mit Überladung erreichen.

Wiederholung constexpr #i n c l u de <a r r a y > c o n s t e x p r i n t exp ( i n t base, i n t n ){ return n > 0? base exp ( base, n 1) : base ; i n t main ( ) { s t d : : a r r a y <int, exp (1024,2) > a r r ;

Wiederholung constexpr Chandler Carruth: But we are not done yet. It that hard. It is harder then variadic templates, I believe it is actually harder then lambdas. It is one of the most challenging to implement correctly features in entire C++11. Bjarne Stroustrup: It is interesting to note, that it is one of these features, that was made more complicated over the dead bodies of its proposers and initial implementors during the standardization.

Wiederholung variadische Templates (1) template<typename... T> s t d : : s t r i n g t e x t (T&&... a r g s ) { s t d : : s t r i n g s t r e a m r e t u r n s t r e a m ; t e x t h e l p e r ( r e t u r n s t r e a m, s t d : : forward <T>( a r g s )... ) ; return r e t u r n s t r e a m. s t r ( ) ;

Wiederholung variadische Templates (2) template<typename T> void t e x t h e l p e r ( s t d : : s t r i n g s t r e a m& stream, T&& arg ) { stream << s t d : : forward <T>( arg ) ; template<typename T, typename... Targs> void t e x t h e l p e r ( s t d : : s t r i n g s t r e a m& stream, T&& arg, argt &&... a r g s ) { stream << s t d : : forward <T>( arg ) ; t e x t h e l p e r ( stream, s t d : : forward <Targs >( a r g s )... ) ;

Typerich Programming Ein einfaches Klassentemplate... template<typename T> c l a s s p o i n t { T x ; T y ; p u b l i c : p o i n t (T x, T y ) : x {x, y {y { T g e t x ( ) { return x ; T g e t y ( ) { return y ; ; i n t main ( ) { i n t x {1, y {2; point <int > p{y, x ; // e r r o r?

Typerich Programming Mehr Typsicherheit (1) template<typename T> c l a s s x c o o r d { T v a l u e ; p u b l i c : x c o o r d (T v a l u e ) : v a l u e { v a l u e { T g e t v a l u e ( ) { return v a l u e ; //... ;

Typerich Programming Mehr Typsicherheit (2) template<typename T> c l a s s p o i n t { x coord <T> x ; y coord <T> y ; p u b l i c : p o i n t ( xcoord<t> x, ycoord<t> y ) : x {x, y {y { x coord <T> g e t x ( ) { return x ; y coord <T> g e t y ( ) { return y ; ; i n t main ( ) { x coord <int > x {1; y coord <int > y {2; point <int > p{x, y ; // no e r r o r

Typerich Programming Übersicht Vorteile Nachteile Typen prüfen Korrektheit Verwendung nicht-trivialer Typen findet nicht-triviale Fehler Ermöglichen weitreichendere Funktionsüberladungen. erhöhte Semantik im Code Aufwand die Typen zu erstellen potentiell viel Codeduplikation Unter Umständen aufwendigere Einarbeitung in den Code

Templateprogrammierung Einführung Naheliegende Lösung: Automatische Typerzeugung Externe Lösungen sind hässlich... Lösung via Präprozessor noch hässlicher und unflexibel. Lösung mit Templates aufwendiger aber möglich, weniger hässlich, potentiell fast beliebig flexibel.

Templateprogrammierung Definition Templatemetaprogramming: Programmierung im Templatesystem/Typsystem einer Programmiersprache zur Berechnung von Typen, Konstanten und Codepfaden während des Kompiliervorgangs.

Templateprogrammierung Um zum Punkt zu kommen (1) #i n c l u de b a s i c n u m b e r. hpp s t r u c t x c o o r d i d { ; template<typename T> using x c o o r d = t y p e b u i l d e r : : basic number <T, x c o o r d i d >; s t r u c t y c o o r d i d { ; template<typename T> using y c o o r d = t y p e b u i l d e r : : basic number <T, y c o o r d i d >;

Templateprogrammierung Um zum Punkt zu kommen (2) template<typename T> c l a s s p o i n t { x coord <T> x ; y coord <T> y ; p u b l i c : p o i n t ( x coord <T> x, y coord <T> y ) : x {x, y {y { x coord <T> g e t x ( ) { return x ; y coord <T> g e t y ( ) { return y ; ; i n t main ( ) { x coord <int > x {1; y coord <int > y {2; point <int > p{x, y ; // no e r r o r ;

Templateprogrammierung Grundlagen der Templateprogrammierung Enums als Konstanten nutzbar rekursive Templates mit Spezialisierungen ermöglichen Rekursion Strikt funktionale Programmiersprache mit Memoisation Berechnungen am Ende des Kompiliervorgangs abgeschlossen Zahlenberechnung dank constexpr nur eingeschränkt sinnvoll

Templateprogrammierung Fibonacci (1) Laufzeit: Θ(n) template<unsigned i n t N> s t r u c t f i b { enum{ v a l u e = f i b <N 1>:: v a l u e + f i b <N 2>:: v a l u e ; ; template<> s t r u c t f i b <1>{ enum{ v a l u e = 1 ; ; template<> s t r u c t f i b <0>{ enum{ v a l u e = 0 ; ;

Templateprogrammierung Fibonacci (2) Laufzeit: Θ(n) template<i n t N> s t r u c t f i b : s t d : : i n t e g r a l c o n s t a n t <u i n t 6 4 t, f i b <N 1>() + f i b <N 2>()> { ; template<> s t r u c t f i b <1> : s t d : : i n t e g r a l c o n s t a n t <int,1> { ; template<> s t r u c t f i b <0> : s t d : : i n t e g r a l c o n s t a n t <int,0> { ;

Templateprogrammierung Fibonacci (3) Laufzeit: Θ(n) template<u i n t 6 4 t N> using Num = s t d : : i n t e g r a l c o n s t a n t <u i n t 6 4 t, N>; template<i n t N> s t r u c t f i b : Num<f i b <N 1>() + f i b <N 2>()> { ; template<> s t r u c t f i b <1> : Num<1> { ; template<> s t r u c t f i b <0> : Num<0> { ;

Templateprogrammierung Fibonacci (4) ( n ) Laufzeit: Θ(fib(n)) = Θ 1+ 5 2, potentiell zur Programlaufzeit. c o n s t e x p r u i n t 6 4 t f i b ( i n t n ){ return n <= 1? n : f i b ( n 1) + f i b ( n 2);

Templateprogrammierung grundlegende Templates namespace s t d { template<bool Tenable, typename T=void> s t r u c t e n a b l e i f { ; template<typename T=void> s t r u c t e n a b l e i f <true, T>{ typedef T type ; ; // namespace s t d

Templateprogrammierung grundlegende Templates namespace s t d { template<typename T1, typename T2> s t r u c t i s s a m e : s t d : : f a l s e t y p e { ; template<typename T> s t r u c t is same <T, T> : s t d : : t r u e t y p e { ; // namespace s t d

Templateprogrammierung grundlegende Templates namespace s t d { template<bool Cond, typename I f t r u e, typename I f f a l s e > s t r u c t c o n d i t i o n a l { typedef I f t r u e type ; ; template<typename I f t r u e, typename I f f a l s e > s t r u c t is same <f a l s e, I f t r u e, I f f a l s e >{ typedef I f f a l s e type ; ; // namespace s t d

Templateprogrammierung SFINAE - substitution failure is not an error (1) template <typename T1, typename T2> auto fun (T1 a, T2 b ) > typename s t d : : e n a b l e i f < s t d : : is same <T1, T2>{, int >:: type { return s t a t i c c a s t <int >(a+b ) ; template <typename T1, typename T2, typename = typename s t d : : e n a b l e i f <! s t d : : is same <T1, T2>{>:: type > double fun (T1 a, T2 b ) { return s t a t i c c a s t <double >(a+b ) ;

Templateprogrammierung SFINAE - substitution failure is not an error (2) i n t main ( ) { // f i r s t f u n c t i o n : auto f = fun ( 1, 1. 0 ) ; // d e c l t y p e ( f ) i s double // second f u n c t i o n : auto i = fun ( 1, 1 ) ; // d e c l t y p e ( i ) i s i n t

Templateprogrammierung static assert static assert ist ein compile-time assert. Da Templates erst bei Verwendung instanziiert werden auch bisweilen nützlich. template<i n t Targ> void fun ( ) { s t a t i c a s s e r t ( ( Targ!=0)&&(Targ==0), This must not be c a l l e d ) ; i n t main (){

Templateprogrammierung Template-Templateargumente Auch Templates können Templateargumente sein. So ist etwa folgendes möglich: #i n c l u de <v e c t o r > template<typename T> using vec = s t d : : v e c t o r <T, s t d : : a l l o c a t o r <T>>; template<typename T, template<typename> c l a s s Tc = vec> c l a s s s a f e c o n t a i n e r : p u b l i c Tc<T> { p u b l i c : s a f e c o n t a i n e r ( ) : Tc<T>(){ T& operator [ ] ( i n t i n d e x ) { return t h i s >at ( i n d e x ) ; ;

Templateprogrammierung Policy-based Design Wie im letzten Beispiel schon zu sehen ist, kann Vererbung auch zum injecten von Methoden und Attributen genutzt werden. Policy-based design Private Vererbung kann hier sehr nützlich sein. Mit öffentlicher Vererbung können Mixins realisiert werden; dies verletzt allerdings schnell das is-a -Kriterium.

Templateprogrammierung Policy-based Design Öffentliche Vererbung zur Runtime zu benutzen, kann aber bei falscher Anwendung zu undefiniertem Verhalten führen: i n t main ( ) { // u n d e f i n e d b e h a v i o u r : // ( and u g l y : i f you r e a l l y need // a p o i n t e r, use a smart one ) s t d : : v e c t o r <int > p t r = new s a f e c o n t a i n e r <int >{; delete p t r ;

Typebuilder Bibliothek zur einfachen Erzeugung von Typen. Primärer Fokus sind Zahlen. reines C++, keine Spracherweiterungen, keine Libs außer der STL; dadurch hochportabel. keine Unterstützung alter Compiler vorgesehen. wo möglich kein Overhead gegenüber nativen Typen. basic number ermöglicht die Erstellung einer Bibliothek für physikalische Einheiten (SI-System) in 160 Zeilen.

Ausblick automatischer Returntype // i n f e r r e d r e t u r n t y p e : const auto f = [ ] ( s t d : : s t r i n g arg ){ return arg += f ; ; // u n t i l C++11: e x p l i c i t r e t u r n t y p e r e q u i r e d : s t d : : s t r i n g g ( s t d : : s t r i n g arg ){ return arg += g ; // the f u t u r e (C++14): auto h ( s t d : : s t r i n g arg ){ return arg += h ;

Ausblick Template-Constraints template<s o r t a b l e Cont> void s o r t ( Cont& c o n t a i n e r ) ; template<typename Cont> r e q u i r e s S o r t a b l e <Cont >() void s o r t ( Cont& cont ) // p o s s i b l e E x t e n s i o n : using C o n t a i n e r { Cont ; // ////////////////// void s o r t ( Cont& c ) ;

Ausblick Liberaleres constexpr Aufhebung der meisten Restriktionen. wichtige Ausnahmen: kein static/thread local, kein goto, keine uninitialisierten Variablen, keine Änderungen an nichtlokalen Variablen.

Sonstiges gefundene Compiler-Bugs: Clang Segfault in clang (Neuentdeckung, mittlerweile gefixt): i n t main ( ) { (1? throw 1 : true )? 1 : throw 2 ;

Sonstiges gefundene Compiler-Bugs: GCC gcc 4.7: falsche Zugriffsrechte (war im trunk bereits gefixt): c l a s s c { i n t f ; p u b l i c : template <typename A> d e c l t y p e ( f ) m(a) const ; ; d e c l t y p e ( c {.m( 0 ) ) i ;

Sonstiges Standard-Issues http://www.open-std.org/jtc1/sc22/wg21/docs/ cwg active.html#1635: #i n c l u de <t y p e t r a i t s > template<bool bar> s t r u c t foo { template<typename T, typename = typename s t d : : e n a b l e i f <bar >:: type> void fun (T){ ; i n t main ( ) { foo<f a l s e > v a r { ;