C++ Templates 2005
description
Transcript of 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) // 4max(-10, -20) // -10
例:関数テンプレート
float max( float x, float y ){ if( x < y ) return y; else return x;}
max( 3.2, 4.4) // 4.4max(-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
fib<10>::val == 55;
int array[55];int array[fib<10>::val];int array[fib(10)]; //error!
● History: “Primzahlen in C++”, Erwin Unruh, 1994– コンパイルすると、エラーメッセージとして素数列を吐くプログラム
Templateを使ったトリック (1)MetaProgramming
class Nil {};template< typename T1,typename T2> class Cons {};
typedef Cons<int, Cons<char, Cons<float,Nil> > > L;
● Typelist
Templateを使ったトリック (1)MetaProgramming
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; };
● Typelist
Templateを使ったトリック (1)MetaProgramming
template<typename T> class is_pointer { static const bool val = false; };
template<typename T> class is_pointer<T*> { static const bool val = true; };
● Type Traits
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
matrix A,B,C,D;A*B // matrix型のオブジェクトA*B+C // matrix型のオブジェクト
D = A*B+C; // まず行列 A*Bを作り // それに Cを加算した行列を作り // Dにコピー
● ”最初の動機は、 Will C++ be faster than Fortran?”
● 行列演算の一時変数の除去
Templateを使ったトリック (2)Expression Template
matrix A,B,C,D;A*B // matrix型のオブジェクトA*B+C // matrix型のオブジェクト
D = A*B+C; // まず行列 A*Bを作り // それに Cを加算した行列を作り // Dにコピー // ↑無駄が多い!!!
● ”最初の動機は、 Will C++ be faster than Fortran?”
● 行列演算の一時変数の除去
Templateを使ったトリック (2)Expression Template
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]
● ”最初の動機は、 Will C++ be faster than Fortran?”
● 行列演算の一時変数の除去
● ↑このくらいの処理で済ませられないか?
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
//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” );
● BNF風記法による文法定義
Templateを使ったトリック (2)Expression Template
● Expression Templateの利用例– 最適化
● 行列演算● 文字列結合演算● printf系の書式化演算
– 式構造の利用 (Domain Specific Language の定義 )
● 文法定義● 無名関数定義● 名前付き関数引数
質問タイム
● なんでも質問どうぞ