5. Introduction
今日のお話
Introduction
●
What's
Benefit
How to use
● C++テンプレート入門
Conclusion
● C++のテンプレートという仕組みを
紹介します
11/12/13 関数型都市忘年会 5
6. Introduction
主な対象者
Introduction
●
What's
Benefit
How to use
● C++や、Cライクな文法の言語を
Conclusion 触ったことがある人
●
テンプレートは使いこなしていない
けど興味がある人
●
テンプレートとか日常的に使いこな
してるけど、発表をひやかしたい人
11/12/13 関数型都市忘年会 6
7. Introduction
〜 本日のレシピ 〜
Introduction
What's
Benefit
How to use ● What's the Template?
Conclusion
●
テンプレートとは?
● What's the Benefit?
●
テンプレートを使うと何が嬉しい?
● How to use the Template.
● テンプレートの使い方/書き方
11/12/13 関数型都市忘年会 7
9. What's the Template?
テンプレートとは?
Introduction
●
What's
Benefit
How to use
● C++の言語機能の一つ
Conclusion ● 1990年7月の会議でC++の規格に取り込まれ
た。
●
型を差し替え可能なクラスや関数を
書くことが出来る仕組み。
●
型とデータ構造とアルゴリズムを
分離できる
●
→コードの再利用性が高い
11/12/13 関数型都市忘年会 9
10. What's the Template?
元々の要望は、コンテナの格納でき
Introduction
●
What's
Benefit る方をパラメータ化したいというこ
How to use
Conclusion
とから
●
標準ライブラリには柔軟で効率のいいコン
テナが必要
● intを格納する動的配列
●
浮動小数点数を格納する線形リスト
●
intからstringへの連想配列、などなど
● C with Classes(C++の前身)の頃は
マクロで対処していた
11/12/13 関数型都市忘年会 10
11. What's the Template?
#define stackdeclare(TYPE)
class stack(TYPE) {
TYPE *min_;
TYPE *max_;
TYPE *top_;
public:
stack(TYPE)(int n);
~stack(TYPE)();
void push(TYPE x);
TYPE pop();
};
11/12/13 関数型都市忘年会 11
14. What's the Template?
ユーザーコードでは
Introduction
●
What's
Benefit
How to use
●
declare(stack, long);のように宣言
Conclusion ● implement(stack, long);のように定義して、
stack(long) sl(1024);
stack(long) sl(1024);
sl.push(123L);
sl.push(123L);
long value = sl.pop();
long value = sl.pop();
のように使う。
11/12/13 関数型都市忘年会 14
15. What's the Template?
マクロの問題点
Introduction
●
What's
Benefit
How to use
Conclusion ●
マクロはただのテキスト処理
●
スコープの概念もない
●
かの有名なmin/maxマクロ(in windows.h)
●
コンパイラサポートがない
●
型安全ではない
●
型推論も出来ない
11/12/13 関数型都市忘年会 15
16. What's the Template?
マクロの問題点
Introduction
●
What's
Benefit
How to use
Conclusion
● 文法がC++のソースと違う。厄介で
面倒でバグのもと
●
複数行のマクロを書こうと思うと末尾の行
の結合が必要
●
引数をカッコで括る必要が有ったりなかっ
たり
●
引数が何度も評価されてしまったり
11/12/13 関数型都市忘年会 16
17. What's the Template?
#define mul2(a,b) (a*b)
void func1()
{
int x = mul2(2, 3);
//=> (2*3) => 6 OK!
int y = mul2(2+1, 3+1);
//=> (2+1*3+1) => 6 !?
//=> mul2(a,b)は、((a)*(b))という形の
//定義じゃないといけない
}
11/12/13 関数型都市忘年会 17
18. What's the Template?
マクロではなく、
Introduction
●
What's
ちゃんと言語機能として
Benefit
How to use
Conclusion
サポートしようという風になった。
11/12/13 関数型都市忘年会 18
19. What's the Template?
Introduction
What's
● Stroustrupが選んだ設計方針案
Benefit
How to use
● Smalltalk風
動的typingと継承を使う
Conclusion
●
● Clu風
● 静的typingと、引数で型を指定できる仕組み
を使う
●
前者はランタイムコストが大きく、
また静的型付け言語であるC++のや
り方と相容れない。
11/12/13 関数型都市忘年会 19
20. What's the Template?
Introduction
What's
● Stroustrupが選んだ設計方針案
Benefit
How to use
● Smalltalk風
動的typingと継承を使う
Conclusion
●
● Clu風
● 静的typingと、引数で型を指定できる仕組み
を使う
●
前者はランタイムコストが大きく、
また静的型付け言語であるC++のや
り方と相容れない。=> 後者を採用
11/12/13 関数型都市忘年会 20
21. What's the Template?
Introduction
What's
● Stroustrupが選んだ設計方針案
Benefit
How to use
● Stroustrup曰く
「理想的には、C++はCluの方法に
Conclusion
基づき、ランタイムとスペース効率
が良く、コンパイル時のオーバー
ヘッドも少ない仕組みを実現した
い、また柔軟性は、Smalltalkのよう
に大きくなければならない」
(D&E第一版 15.2 P.431)
11/12/13 関数型都市忘年会 21
22. What's the Template?
そうして出来上がったのが今のテン
Introduction
●
What's
Benefit プレート
How to use
Conclusion
11/12/13 関数型都市忘年会 22
23. What's the Template?
template<class T>
class ClassA
{
T value_;
};
template<class T>
int FunctionB(T arg)
{
arg.get_value();
}
11/12/13 関数型都市忘年会 23
24. What's the Template?
そうして出来上がったのが今のテン
Introduction
●
What's
Benefit プレート
How to use
Conclusion
●
テンプレート化したクラス
● => クラステンプレート
template<class T>
template<class T>
class ClassA
class ClassA
{
{
T
T value_;
value_;
};
};
11/12/13 関数型都市忘年会 24
25. What's the Template?
そうして出来上がったのが今のテン
Introduction
●
What's
Benefit プレート
How to use
Conclusion
●
テンプレート化した関数
● => 関数テンプレート
template<class T>
template<class T>
int FunctionB(T arg)
int FunctionB(T arg)
{
{
arg.get_value();
arg.get_value();
}
}
11/12/13 関数型都市忘年会 25
26. What's the Template?
こんな感じで使えるという例
Introduction
●
What's
Benefit
How to use
Conclusion
11/12/13 関数型都市忘年会 26
27. What's the Template?
こんな感じで使えるという例
Introduction
●
What's
Benefit
How to use template<
template<
Conclusion class T, Alloc = std::allocator<T>
class T, Alloc = std::allocator<T>
>
>
class vector
class vector
{
{
size_t
size_t size () const;
size () const;
T &
T & front ();
front ();
T const & front () const;
T const & front () const;
//その他ごにょごにょ
//その他ごにょごにょ
};
};
●
こんな定義のクラステンプレート
11/12/13 関数型都市忘年会 27
31. What's the Template?
もうひとつの例
Introduction
●
What's
Benefit
How to use
Conclusion ●
二つの変数が与えられたときに、比
較して小さい方を返す。
11/12/13 関数型都市忘年会 31
32. What's the Template?
Introduction
What's
● minマクロ
Benefit
How to use #define min(a,b) ((a)<(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
Conclusion
●
関数で実装するなら・・・?
?? min(?? a, ?? b) {
?? min(?? a, ?? b) {
return a < b ? a : b;
return a < b ? a : b;
}
}
11/12/13 関数型都市忘年会 32
33. What's the Template?
マクロはあんまり良くないので、関
Introduction
●
What's
Benefit 数で書きたい
でも、こんな汎用的な処理を色んな
How to use
●
Conclusion
型のバージョンで分けて書いていら
れない(そもそもユーザー定義型に
も対応したい)
11/12/13 関数型都市忘年会 33
34. What's the Template?
比較可能であることを表す、
Introduction
●
What's
Benefit IComparableから派生したクラスの
How to use
Conclusion
変数だけを受け取って、仮想関数
compareで比較する?
●
POD型に対応できない。
●
比較するだけで仮想関数の仕組みを使わな
くてはいけないのは嬉しくない。
11/12/13 関数型都市忘年会 34
35. What's the Template?
先程の??の型は(a < b)が定義されて
Introduction
●
What's
Benefit
る型なら何でもいい
How to use
Conclusion ●
テンプレート化
template<class T>
template<class T>
T const & min(T const &a, T const &b)
T const & min(T const &a, T const &b)
{
{
return a < b ? a : b;
return a < b ? a : b;
//中味はさっきと全く一緒でおk。
//中味はさっきと全く一緒でおk。
}
}
●
型安全なまま、抽象度の高いプログ
ラムが書ける
11/12/13 関数型都市忘年会 35
36. What's the Template?
テンプレートには、型だけではな
Introduction
●
What's
Benefit く、コンパイル時定数を使用するこ
How to use
Conclusion
とも出来る。
template<int N>
template<int N>
struct twice
struct twice
{
{
static const int value =
static const int value =
N + N;
N + N;
};
};
11/12/13 関数型都市忘年会 36
73. How to use the Template.
テンプレートの使い方/書き方
Introduction
●
What's
クラステンプレート
Benefit
●
How to use
Conclusion ●
関数テンプレート
11/12/13 関数型都市忘年会 73
74. How to use the Template.
クラステンプレートの使い方
Introduction
●
What's
Benefit
How to use
Conclusion
11/12/13 関数型都市忘年会 74
75. How to use the Template.
クラステンプレートの使い方
Introduction
●
What's
Benefit
How to use std::vector<int>
std::vector<int> vs;
vs;
Conclusion
//長ければtypedefして
//長ければtypedefして
typedef std::vector<int> int_vector;
typedef std::vector<int> int_vector;
int_vector
int_vector vs2;
vs2;
11/12/13 関数型都市忘年会 75
76. How to use the Template.
クラステンプレートの使い方
Introduction
●
What's
Benefit
How to use //2引数を取るようなクラステンプレートには
//2引数を取るようなクラステンプレートには
Conclusion //カンマ区切りでテンプレート型を指定する
//カンマ区切りでテンプレート型を指定する
typedef
typedef
std::pair<std::string, double>
std::pair<std::string, double>
pair_t;
pair_t;
11/12/13 関数型都市忘年会 76
77. How to use the Template.
クラステンプレートの使い方
Introduction
●
What's
Benefit
How to use
//入れ子になったテンプレート
//入れ子になったテンプレート
Conclusion
typedef std::list<std::list<int> >
typedef std::list<std::list<int> >
11/12/13 関数型都市忘年会 77
78. How to use the Template.
クラステンプレートの使い方
Introduction
●
What's
Benefit
How to use
//入れ子になったテンプレート
//入れ子になったテンプレート
Conclusion
typedef std::list<std::list<int> >
typedef std::list<std::list<int> >
●
入れ子になったテンプレート引数を指定す
るとき、右の山括弧の間にスペースを空けな
いと、operator>>と解釈が曖昧になるの
で、スペースが必要
● C++11からスペース開けなくてもよくなった
●
C++03のコンパイラでも、スペース開けなく
てもいいものもある。
11/12/13 関数型都市忘年会 78
79. How to use the Template.
クラステンプレートの書き方
Introduction
●
What's
Benefit
How to use
template<class T>
template<class T>
Conclusion
struct ParameterizedClass
struct ParameterizedClass
{ /*ごにょごにょ*/ };
{ /*ごにょごにょ*/ };
template<typename T>
template<typename T>
struct ParameterizedClass
struct ParameterizedClass
{ /*ごにょごにょ*/ };
{ /*ごにょごにょ*/ };
●
普通のクラス定義の直前に
template<class T>のようにして、パ
ラメータ化する型を書く
11/12/13 関数型都市忘年会 79
80. How to use the Template.
クラステンプレートの書き方
Introduction
●
What's
Benefit
How to use
template<class T>
template<class T>
Conclusion
struct ParameterizedClass
struct ParameterizedClass
{ /*ごにょごにょ*/ };
{ /*ごにょごにょ*/ };
template<typename T>
template<typename T>
struct ParameterizedClass
struct ParameterizedClass
{ /*ごにょごにょ*/ };
{ /*ごにょごにょ*/ };
● Tには好きな型名を付ける
● 型の指定はclass/typename どちらで
も良い
11/12/13 関数型都市忘年会 80
81. How to use the Template.
クラステンプレートの書き方
Introduction
●
What's
Benefit
How to use template<class T>
template<class T>
Conclusion
struct ParameterizedClass
struct ParameterizedClass
{
{
T member_variable_;
T member_variable_;
T const & get_value () const
T const & get_value () const
{
{ return member_variable_; }
return member_variable_; }
void set_value (T const &new_value)
void set_value (T const &new_value)
{
{ member_variable_ = new_value; }
member_variable_ = new_value; }
};
};
●
クラス内部では、既知の型のように
テンプレートを使用できる。
11/12/13 関数型都市忘年会 81
82. How to use the Template.
クラステンプレートの書き方
Introduction
●
What's
Benefit
typedef
typedef
How to use
ParameterizedClass<int>
ParameterizedClass<int>
Conclusion default_params_t;
default_params_t;
● このままだと、default_params_tの
利用者がdefault_params_tから、
ParameterizedClassになんの型が渡
されたかを取得する方法がない
11/12/13 関数型都市忘年会 82
83. How to use the Template.
クラステンプレートの書き方
Introduction
●
What's
もし、クラステンプレートに渡され
Benefit
●
たテンプレート引数を、クラス外部
How to use
Conclusion
からも取得できるようにするには、
メタ関数を用いる。
template<class T>
template<class T>
struct ParametrizedClass
struct ParametrizedClass
{
{
typedef T value_type;
typedef T value_type;
};
};
11/12/13 関数型都市忘年会 83
84. How to use the Template.
クラステンプレートの書き方
Introduction
●
What's
これで、先程のdefault_params_tか
Benefit
●
How to use
Conclusion ら
default_params_t::value_type;
default_params_t::value_type;
元々のクラステンプレートに渡され
た型を取得できました。
●
余談ですが、このdefault_params_tは、引
数なしメタ関数と呼ばれるものです。詳し
くはC++テンプレートメタプログラミング
(デビッド・アブラハムズ, アレクセイ・グ
ルトヴォイ)を参照してください
11/12/13 関数型都市忘年会 84
85. How to use the Template.
クラステンプレートの書き方
Introduction
●
What's
複数のテンプレート引数はカンマ区
Benefit
●
切りで指定する。
How to use
Conclusion
template<class T1, class T2>
template<class T1, class T2>
struct ParameterizedClass2
struct ParameterizedClass2
{ /*ごにょごにょ*/ };
{ /*ごにょごにょ*/ };
11/12/13 関数型都市忘年会 85
86. How to use the Template.
クラステンプレートの書き方
Introduction
●
What's
もっとも後ろのテンプレート引数か
Benefit
●
ら順に、デフォルト引数を指定でき
How to use
Conclusion
る template<
template<
class
class T1,
T1,
class
class T2 =
T2 = void,
void,
class
class T3 =
T3 = void,
void,
class
class T4 =
T4 = void
void
>
>
struct ManyParamClass
struct ManyParamClass
{ /*ごにょごにょ*/ };
{ /*ごにょごにょ*/ };
●
頻繁に指定される引数を省略できる
11/12/13 関数型都市忘年会 86
87. How to use the Template.
関数テンプレートの使い方
Introduction
●
What's
Benefit
How to use
Conclusion
11/12/13 関数型都市忘年会 87
88. How to use the Template.
関数テンプレートの使い方
Introduction
●
What's
Benefit
How to use
Conclusion template<class T>
template<class T>
T const & min(
T const & min(
T const &a,
T const &a,
T const &b
T const &b
)
)
{
{
return a < b ? a : b;
return a < b ? a : b;
}
}
11/12/13 関数型都市忘年会 88
89. How to use the Template.
関数テンプレートの使い方
Introduction
●
What's
Benefit
How to use
Conclusion int const m =
int const m =
std::min(3, 4);
std::min(3, 4);
//assert(m == 3);
//assert(m == 3);
//windows.hでminマクロが
//windows.hでminマクロが
//定義されているときの
//定義されているときの
//workaround
//workaround
int const m =
int const m =
(std::min)(3, 4);
(std::min)(3, 4);
//関数をカッコで括っても呼び出せる
//関数をカッコで括っても呼び出せる
11/12/13 関数型都市忘年会 89
90. How to use the Template.
関数テンプレートの使い方
Introduction
●
What's
引数からテンプレートの型が推論で
Benefit
●
きる場合は、テンプレート引数を指
How to use
Conclusion
定する必要はない。
11/12/13 関数型都市忘年会 90
91. How to use the Template.
関数テンプレートの書き方
Introduction
●
What's
Benefit
How to use
template<class T>
template<class T>
Conclusion
void func(T const &t)
void func(T const &t)
{
{
t.get_value();
t.get_value();
}
}
11/12/13 関数型都市忘年会 91
92. How to use the Template.
関数テンプレートの書き方
Introduction
●
What's
Benefit
How to use
template<class T>
template<class T>
Conclusion
void func(T const &t)
void func(T const &t)
{
{
t.get_value();
t.get_value();
}
}
*残りの説明は未実装。。。
11/12/13 関数型都市忘年会 92