www.kmonos.net

Download Report

Transcript www.kmonos.net

C++ Templates 2005
稲葉 一浩
[email protected]
発表の流れ
●
●
基本編
–
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に似た技術
●
最上位の基底型
–
●
Parametric Polymorphism
–
●
JavaのObjectクラスなど
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>
map { ... };
–
template<typename T> class stack { ... };
「アルゴリズム」の関数テンプレート
–
find, sort, make_heap, random_shuffle, ...
class
発表の流れ
●
●
基本編
–
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
●
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 の定義)
●
文法定義
●
無名関数定義
●
名前付き関数引数
質問タイム
●
なんでも質問どうぞ