12
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

テンプレートが手招きしているよ

Posted at

#テンプレートが手招きしているよ
本記事は「初心者 C++er Advent Calendar 2015」
最終日の記事です!
毎度おなじみ(?)、C++とテンプレートが大好き
いなむ先生です

C++のテンプレートで型を変数にすることについて書きます
「使いなさい」と言うつもりはありません
テンプレートとは__コンパイル時に型や値を引数として渡す機能__である
ということが言いたいだけです

実際、怖くない!

よくわからない?
とりあえず、読んでみてよ!
さあ、楽しいテンプレートの世界へ!れっつらごー!

##関数テンプレート

C++にはオーバーロードという機能があります
引数の型が異なる同じ名前の関数を定義できます
以下のmax関数はintdoubleでオーバーロードされています

同じ処理を行っているにも関わらず、関数を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)を推測する
上の例の場合はTintとなる
これをテンプレート仮引数の推測(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からは変数もテンプレートにできます
例えば、円周率を定数として定義したいことはよくあります
intdoubleについて、いちいち定義するのはばからしいです
そこで、テンプレート!
こんな風にするよ!

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...型名が...とっても長いです(´・ω・`)
ET.png

##おわりに
くどいくらいに
型を変数化__しておいて、...
と言いましたが、言いたいことはそれだけです
「テンプレートとは何か?」ときかれたら
「なんか怖いやつ」等と言わずに
「コンパイル時に型や値を引数として渡す機能」__といいましょう

##跋文
テンプレートは楽しいし
C++の真のパワーを開花させる機能です
しかし、ご利用は計画的に

最後まで付き合って読んでくれた方、ありがとうございました
ミスの指摘や質問はコメントか
|いなむ先生|Twitter
までお願いします

12
12
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?