390 likes | 517 Views
稲葉 一浩 kinaba@is.s.u-tokyo.ac.jp. C++ Templates 2005. 発表の流れ. 基本編 Templateとは何ぞや Templateの当初の目的( STL ) 応用編 その後に考案されたテクニック色々 Traits, Policy, Mix-in Meta-programming Type Erasure Expression Template, EDSL Concept-Controlled Polymorphism. C++の歴史.
E N D
稲葉 一浩 kinaba@is.s.u-tokyo.ac.jp C++ Templates 2005
発表の流れ • 基本編 • Templateとは何ぞや • Templateの当初の目的( STL ) • 応用編 • その後に考案されたテクニック色々 • Traits, Policy, Mix-in • Meta-programming • Type Erasure • Expression Template, EDSL • Concept-Controlled Polymorphism
C++の歴史 • 1979: Bjarne Stroustrup により、言語 “C with Classes” が作られる。 • 1983: “C++” に改名。 • 1985: 初の商用コンパイラが出る。 • 1989: C++ 2.0。多重継承、抽象クラス、protected。 • 1990: C++ 3.0。Template、例外、名前空間、bool型、…。 • 1998: ISOの国際規格になる。
Templateとは? • 特定の型に依存しないプログラムの記述 • クラステンプレート • 関数テンプレート
例:クラステンプレート class LinkedList1 { class Node { int value; Node* next; }; Node* head; ... }; LinkedList1 intList;
例:クラステンプレート class LinkedList2 { class Node { string value; Node* next; }; Node* head; ... }; LinkedList2 strList;
例:クラステンプレート template<typename ValueType> class LinkedList { class Node { ValueType value; Node* next; }; Node* head; ... }; LinkedList<int> intList; LinkedList<string> strList;
例:クラステンプレート • 特定の型に依存しないプログラムの記述 • 型をパラメータとして取り出す template<typename T> class HogeTmpl { T field; T method( T x ) {return x;} }; HogeTmpl<int> a; HogeTmpl<string> b;
例:関数テンプレート int max( int x, int y ) { if( x < y ) return y; else return x; } max( 3, 4) // 4 max(-10, -20) // -10
例:関数テンプレート float max( float x, float y ) { if( x < y ) return y; else return x; } max( 3.2, 4.4) // 4.4 max(-10.1, 0.0) // -10.1
例:関数テンプレート template<typename T> T max( T x, T y ) { if( x < y ) return y; else return x; } max<int>( 3, 4) max<int>(-10, -20) max<float>( 3.2, 4.4) max<float>(-10.1, 0.0)
例:関数テンプレート • 特定の型に依存しないプログラムの記述 • 型をパラメータとして取り出す template<typename T> T hogeFunc( int x, T y ) { T value; ... } hogeFunc<int>(10,20); hogeFunc<string>(10,“Hello”);
例:関数テンプレート • 型推論 • 引数の型からTemplateのパラメタが推論できる場合、明示指定しなくてもよい template<typename T> T max( T x, T y ) { if( x < y ) return y; else return x; } max( 3, 4) max(3.2, 4.4)
コンパイル方法 • Templateに具体的な型が適用されたら、その実体を全部作る! template<typename T> T max( T x, T y ) { ... } max<int>( 3, 4); max<float>(3.2, 4.4); int max<int>( int x, int y){...} float max<float>(float x, float y){...} max<int>( 3, 4); max<float>(3.2, 4.4);
コンパイル方法 • Templateに具体的な型が適用されたら、その実体を全部作る! • n種類の型でTemplate関数/クラスを作ったら、n個の機械語コードにコンパイルされる。 • 生成されるコードが肥大化しがち。
Template色々 • 参考資料をご覧下さい • 引数いろいろ • 特殊化
参考:Templateに似た技術 • 最上位の基底型 • JavaのObjectクラスなど • Parametric Polymorphism • ML, OCaml • Generics • Java2 5.0, C# 2.0
STL ( Standard Template Library ) • 1993: Alex Stephanov • 「データ構造」のクラステンプレート • template<typename T> class vector { ... }; • template<typename T> class list { ... }; • template<typename T> class set { ... }; • template<typename Key, typename T> class map { ... }; • template<typename T> class stack { ... }; • 「アルゴリズム」の関数テンプレート • find, sort, make_heap, random_shuffle, ...
発表の流れ • 基本編 • Templateとは何ぞや • Templateの当初の目的( STL ) • 応用編 • その後に考案されたテクニック色々 • Traits, Policy, Mix-in • Meta-programming • Type Erasure • Expression Template, EDSL • Concept-Controlled Polymorphism
Templateを使ったトリック(1)MetaProgramming • クラステンプレート • 型パラメータを与えると、型を返す… 型から型への関数!? • “返値”である”クラス”は、メンバ関数やメンバ定数、内部クラス等、いろいろな情報を返すことができる。 • テンプレートの特殊化 • パラメータによる場合分け • パラメータによる条件分岐!?
Templateを使ったトリック(1)MetaProgramming • “返値”である”クラス”は、メンバ関数やメンバ定数、内部クラス等、いろいろな情報を返すことができる。 template<typename T> class MyTemplate { static const int C = 100; int func(){ ... } class Hoge { T x; }; typedef list<T> lit; };
Templateを使ったトリック(1)MetaProgramming int fib( int N ) { if( N==0 ) return 1; if( N==1 ) return 1; return fib(N-1)+fib(N-2); }
Templateを使ったトリック(1)MetaProgramming template<int N> class fib { static const int val = fib<N-1>::val + fib<N-2>::val }; template<> class fib<0> { static const int val = 1 }; template<> class fib<1> { static const int val = 1 };
Templateを使ったトリック(1)MetaProgramming • History: “Primzahlen in C++”, Erwin Unruh, 1994 • コンパイルすると、エラーメッセージとして素数列を吐くプログラム fib<10>::val == 55; int array[55]; int array[fib<10>::val]; int array[fib(10)]; //error!
Templateを使ったトリック(1)MetaProgramming • Typelist class Nil {}; template< typename T1,typename T2> class Cons {}; typedef Cons<int, Cons<char, Cons<float,Nil> > > L;
Templateを使ったトリック(1)MetaProgramming • Typelist template<typename Lst> class length; template<> class length<Nil> { static const int val = 0; }; template<typename Hd,typename Tl> class length< Cons<Hd,Tl> > { static const int val = 1 + length<Tl>::val; };
Templateを使ったトリック(1)MetaProgramming • Type Traits template<typename T> class is_pointer { static const bool val = false; }; template<typename T> class is_pointer<T*> { static const bool val = true; };
Templateを使ったトリック(1)MetaProgramming • MetaProgrammingの利用例 • 定数表のコンパイル時計算 • FFT( sin, cos 定数の計算 ) • 複雑なクラスの自動合成 • デザインパターンのコード化 • オートマトンの遷移表から、入力記号を受け取って状態遷移して遷移イベント関数を呼び出してetc…というクラスを生成 • 他のTemplate技術の下支え
発表の流れ • 基本編 • Templateとは何ぞや • Templateの当初の目的( STL ) • 応用編 • その後に考案されたテクニック色々 • Traits, Policy, Mix-in • Meta-programming • Type Erasure • Expression Template, EDSL • Concept-Controlled Polymorphism
Templateを使ったトリック(2)Expression Template • 最初の動機は、”Will C++ be faster than Fortran?” • 行列演算の一時変数の除去 matrix A,B,C,D; A*B // matrix型のオブジェクト A*B+C // matrix型のオブジェクト D = A*B+C; // まず行列A*Bを作り // それにCを加算した行列を作り // Dにコピー
Templateを使ったトリック(2)Expression Template • 最初の動機は、”Will C++ be faster than Fortran?” • 行列演算の一時変数の除去 matrix A,B,C,D; A*B // matrix型のオブジェクト A*B+C // matrix型のオブジェクト D = A*B+C; // まず行列A*Bを作り // それにCを加算した行列を作り // Dにコピー // ↑無駄が多い!!!
Templateを使ったトリック(2)Expression Template • 最初の動機は、”Will C++ be faster than Fortran?” • 行列演算の一時変数の除去 D = A*B+C; for(i=1; i<N; ++i) for(j=1; j<N; ++j) D[i][j] = Σ(A[i][k]*B[k][j]) + C[i][j] • ↑このくらいの処理で済ませられないか?
Templateを使ったトリック(2)Expression Template • 解決策(資料参照) • 式の値を、計算結果の行列ではなく、「計算式の構造情報」とする。 • 代入の際に、右辺の式の構造を元に成分毎に値を計算する。 A*B //mul<matrix,matrix>型 A*B+C //add<mul<matrix,matrix>,matrix> //型
Templateを使ったトリック(2)Expression Template • Expression Template まとめ • 途中式の値を計算せず、「式の構造」をtemplateを重ねて保持しておく。 • 式全体の形が確定した後で、その式の形に基づいて処理。 • という最適化技法。
Templateを使ったトリック(2)Expression Template • Expression Template まとめ • 途中式の値を計算せず、「式の構造」をtemplateを重ねて保持しておく。 • 式全体の形が確定した後で、その式の形に基づいて処理。 • という最適化技法。 • 「式の構造」に基づいて別種のオブジェクトを生成するための技法としても使用される。
Templateを使ったトリック(2)Expression Template • 無名関数の記述 var1 X; var2 Y; X+Y*2-1 // sub< // add< // var1, // mul<var2,constant>, // >,constant> > lambda( X+Y*2-1 )
Templateを使ったトリック(2)Expression Template • BNF風記法による文法定義 //Ex ::= Tm ('+' Tm)* //Tm ::= Fc ('*' Fc)* //Fc ::= '(' Ex ')' // | '1' | ... | '9' rule Ex,Tm,Fc; Ex = Tm >> *('+' >> Tm); Tm = Fc >> *('*' >> Fc); Fc = '(' >> Ex >> ')' | '1' | ... | '9'; Ex.match( “1+2*3” );
Templateを使ったトリック(2)Expression Template • Expression Templateの利用例 • 最適化 • 行列演算 • 文字列結合演算 • printf系の書式化演算 • 式構造の利用(Domain Specific Language の定義) • 文法定義 • 無名関数定義 • 名前付き関数引数
質問タイム • なんでも質問どうぞ