#テンプレートが手招きしているよ
本記事は「初心者 C++er Advent Calendar 2015」
最終日の記事です!
毎度おなじみ(?)、C++とテンプレートが大好き
いなむ先生です
C++のテンプレートで型を変数にすることについて書きます
「使いなさい」と言うつもりはありません
テンプレートとは__コンパイル時に型や値を引数として渡す機能__である
ということが言いたいだけです
実際、怖くない!
よくわからない?
とりあえず、読んでみてよ!
さあ、楽しいテンプレートの世界へ!れっつらごー!
##関数テンプレート
C++にはオーバーロードという機能があります
引数の型が異なる同じ名前の関数を定義できます
以下のmax関数はint
とdouble
でオーバーロードされています
同じ処理を行っているにも関わらず、関数を2つも書いています
同じことを書くのは面倒で、バグのもとです
int max( int a, int b ) // #1
{
return a < b ? b : a ;
}
double max( double a, double b ) // #2
{
return a < b ? b : a ;
}
int main(){
max( 1, 2 ) ; // 1,2はintなので#1が呼ばれる
max( 1.5, 2.3 ) ; // 1.5,2.3はdoubleなので#2が呼ばれる
}
そこでC++ではテンプレートを用いて
template < typename T >
T max( T a, T b )
{
return a < b ? b : a ;
}
と書くことができる
これは、
max( 1, 2 ) ;
のように呼び出すと、引数からテンプレート仮引数(T
)を推測する
上の例の場合はT
はint
となる
これをテンプレート仮引数の推測(Template Argument Deduction)と呼ぶ
難しいことはおいておいて、
ここで、テンプレートの宣言をよく見てみよう
template < typename T >
T max( T a, T b )
template < typename T >
template
:テンプレートであることの宣言、一番最初に書く
<>
:この中に変数化する型の変数名(テンプレート仮引数)を書く
typename, class
:これに続くのはテンプレート仮引数だよ、という合図(ふつうはどっちでも良い)
この後に続けて関数を書きます
そして型名をテンプレート仮引数にします
T max( T a, T b )
要するに、使うまで__型を変数化__しておいて、__呼び出しから型を推測__する
ちなみに
型を推測させずに、自分で指定することもできます
その場合は関数名と呼び出しの()
の間に<>
を書いてその中に型を指定します
max< int >( 1, 2 );
##クラステンプレート
クラスをテンプレートにできる
初心者はクラスを書かないと思われるので紹介だけ
例えば、クラスのメンバ変数の型をテンプレートをテンプレートにできる
2次元の座標を表すクラスを作るとする
template < typename T >
struct pos_2d{
T x = T{} ;
T y = T{} ;
} ;
座標がint
型なのかdouble
型なのか
使うまでわからなくても、使うときに指定できる
auto&& pos = pos_2d<int>{ 20, 20 } ;
要するに、__型を変数化__しておいて、__使うときに指定__する
##変数テンプレート
C++14からは変数もテンプレートにできます
例えば、円周率を定数として定義したいことはよくあります
int
やdouble
について、いちいち定義するのはばからしいです
そこで、テンプレート!
こんな風にするよ!
template < typename T >
constexpr T PI = static_cast<T>(3.14159265358979323846L) ;
int main(){
std::cout << PI<int> << std::endl;; // 3
std::cout << PI<double> << std::endl; // 3.14159
}
要するに、__型を変数化__しておいて、__使うときに指定__する
##ダークサイド
何をもってダークサイドというのか定かではありませんが
テンプレートのダークサイドを使うと楽しいです
三へ( へ՞ਊ ՞)へ ハッハッ
いなむ先生は最近Expression Templateというちょっとしたテクニックを使っていますが
二度と書きたく とっても楽しいです
画像はExpression Template が生成した型名をVisual Studio2015の機能で表示してみたもの(プロ生ちゃんカ・ワ・イ・イ)
Oh, Gosh...型名が...とっても長いです(´・ω・`)
##おわりに
くどいくらいに
型を変数化__しておいて、...
と言いましたが、言いたいことはそれだけです
「テンプレートとは何か?」ときかれたら
「なんか怖いやつ」等と言わずに
「コンパイル時に型や値を引数として渡す機能」__といいましょう
##跋文
テンプレートは楽しいし
C++の真のパワーを開花させる機能です
しかし、ご利用は計画的に
最後まで付き合って読んでくれた方、ありがとうございました
ミスの指摘や質問はコメントか
|いなむ先生|Twitter
までお願いします