C++ テンプレート入門




            @hotwatermorning

11/12/13        関数型都市忘年会       1
自己紹介
●   @hotwatermorning
●
    C++でプログラム書いてます。




11/12/13     関数型都市忘年会   2
自己紹介
●
    Boost.勉強会 #6 札幌を開催しました!




11/12/13     関数型都市忘年会         3
Introduction




11/12/13      関数型都市忘年会    4
Introduction
                    今日のお話
Introduction
                ●
  What's
  Benefit
How to use
                ●   C++テンプレート入門
Conclusion
                ●   C++のテンプレートという仕組みを
                    紹介します




               11/12/13          関数型都市忘年会   5
Introduction
                    主な対象者
Introduction
                ●
  What's
  Benefit
How to use
                ●   C++や、Cライクな文法の言語を
Conclusion          触ったことがある人
                ●
                    テンプレートは使いこなしていない
                    けど興味がある人
                ●
                    テンプレートとか日常的に使いこな
                    してるけど、発表をひやかしたい人



               11/12/13          関数型都市忘年会   6
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
What's the Template?




11/12/13          関数型都市忘年会        8
What's the Template?
                    テンプレートとは?
Introduction
                ●
  What's
  Benefit
How to use
                ●   C++の言語機能の一つ
Conclusion          ●     1990年7月の会議でC++の規格に取り込まれ
                          た。
                ●
                    型を差し替え可能なクラスや関数を
                    書くことが出来る仕組み。
                ●
                    型とデータ構造とアルゴリズムを
                    分離できる
                ●
                    →コードの再利用性が高い
               11/12/13           関数型都市忘年会          9
What's the Template?
                    元々の要望は、コンテナの格納でき
Introduction
                ●
  What's
  Benefit           る方をパラメータ化したいというこ
How to use
Conclusion
                    とから
                    ●
                          標準ライブラリには柔軟で効率のいいコン
                          テナが必要
                    ●     intを格納する動的配列
                    ●
                          浮動小数点数を格納する線形リスト
                    ●
                          intからstringへの連想配列、などなど
                ●   C with Classes(C++の前身)の頃は
                    マクロで対処していた
               11/12/13            関数型都市忘年会        10
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
What's the Template?
#define stackimplement(TYPE) 
stack(TYPE)::stack(TYPE)(int n) { 
    min_ = top_ = new TYPE(n); 
    max_ = min_ + n; 
} 
stack(TYPE)::~stack(TYPE)() { 
    delete[] min_; 
} 
void stack(TYPE)::push(TYPE x) { 
    assert(top_ != min_); 
    *top_++ = x; 
} 
    こんな感じで行を結合しながら書いていく・・・
11/12/13          関数型都市忘年会            12
What's the Template?
#define name2(X,Y) X/**/Y
    => トークンペーストマクロ
    => 現在の仕様では X##Yとする

#define declare(CLASS,TYPE) 
    name2(CLASS,declare)(TYPE)

#define implement(CLASS,TYPE)
    name2(CLASS,implement)(TYPE)

#define stack(TYPE) name2(stack,TYPE)

11/12/13              関数型都市忘年会          13
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
What's the Template?
                    マクロの問題点
Introduction
                ●
  What's
  Benefit
How to use
Conclusion      ●
                    マクロはただのテキスト処理
                    ●
                          スコープの概念もない
                    ●
                          かの有名なmin/maxマクロ(in windows.h)
                ●
                    コンパイラサポートがない
                    ●
                          型安全ではない
                    ●
                          型推論も出来ない


               11/12/13             関数型都市忘年会              15
What's the Template?
                    マクロの問題点
Introduction
                ●
  What's
  Benefit
How to use
Conclusion
                ●   文法がC++のソースと違う。厄介で
                    面倒でバグのもと
                    ●
                          複数行のマクロを書こうと思うと末尾の行
                          の結合が必要
                    ●
                          引数をカッコで括る必要が有ったりなかっ
                          たり
                    ●
                          引数が何度も評価されてしまったり


               11/12/13         関数型都市忘年会        16
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
What's the Template?
                    マクロではなく、
Introduction
                ●
  What's

                    ちゃんと言語機能として
  Benefit
How to use
Conclusion
                    サポートしようという風になった。




               11/12/13        関数型都市忘年会    18
What's the Template?
Introduction
  What's
                ●   Stroustrupが選んだ設計方針案
  Benefit
How to use
                ●   Smalltalk風
                          動的typingと継承を使う
Conclusion
                    ●


                ●   Clu風
                    ●     静的typingと、引数で型を指定できる仕組み
                          を使う
                ●
                    前者はランタイムコストが大きく、
                    また静的型付け言語であるC++のや
                    り方と相容れない。

               11/12/13            関数型都市忘年会     19
What's the Template?
Introduction
  What's
                ●   Stroustrupが選んだ設計方針案
  Benefit
How to use
                ●   Smalltalk風
                          動的typingと継承を使う
Conclusion
                    ●


                ●   Clu風
                    ●     静的typingと、引数で型を指定できる仕組み
                          を使う
                ●
                    前者はランタイムコストが大きく、
                    また静的型付け言語であるC++のや
                    り方と相容れない。=> 後者を採用

               11/12/13            関数型都市忘年会     20
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
What's the Template?
                    そうして出来上がったのが今のテン
Introduction
                ●
  What's
  Benefit           プレート
How to use
Conclusion




               11/12/13        関数型都市忘年会    22
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
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
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
What's the Template?
                    こんな感じで使えるという例
Introduction
                ●
  What's
  Benefit
How to use
Conclusion




               11/12/13        関数型都市忘年会    26
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
What's the Template?
                    こんな感じで使えるという例
Introduction
                ●
  What's
  Benefit
How to use           //int型の要素を持つvectorクラス
                     //int型の要素を持つvectorクラス
Conclusion           std::vector<int> is;
                     std::vector<int> is;
                     //char型の要素を持つvectorクラス
                     //char型の要素を持つvectorクラス
                     std::vector<char> cs;
                     std::vector<char> cs;
                     //std::string型の要素をもつvectorクラス
                     //std::string型の要素をもつvectorクラス
                     std::vector<std::string> ss;
                     std::vector<std::string> ss;
                     //なんらかのユーザー定義型を要素に持つ
                     //なんらかのユーザー定義型を要素に持つ
                     //vectorクラス
                     //vectorクラス
                     std::vector<SomeUserDefinedType> us;
                     std::vector<SomeUserDefinedType> us;
               11/12/13            関数型都市忘年会                 28
What's the Template?
                    こんな感じで使えるという例
Introduction
                ●
  What's
  Benefit
How to use                is.size();
                          is.size();
Conclusion                cs.size();
                          cs.size();
                          ss.size();
                          ss.size();
                          us.size();
                          us.size();
                ●
                    全部使い方一緒!




               11/12/13                関数型都市忘年会   29
What's the Template?
                    こんな感じで使えるという例
Introduction
                ●
  What's
  Benefit
How to use
                      is.front(); //(int &)
                      is.front(); //(int &)
                      cs.front(); //(char &)
                      cs.front(); //(char &)
Conclusion
                      ss.front(); //(std::string &)
                      ss.front(); //(std::string &)
                      us.front(); //(SomeUserDefinedType &)
                      us.front(); //(SomeUserDefinedType &)

                ●
                    それぞれ指定した型で要素を取得で
                    きる!!




               11/12/13             関数型都市忘年会                  30
What's the Template?
                    もうひとつの例
Introduction
                ●
  What's
  Benefit
How to use
Conclusion      ●
                    二つの変数が与えられたときに、比
                    較して小さい方を返す。




               11/12/13        関数型都市忘年会    31
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
What's the Template?
                    マクロはあんまり良くないので、関
Introduction
                ●
  What's
  Benefit           数で書きたい
                    でも、こんな汎用的な処理を色んな
How to use
                ●
Conclusion

                    型のバージョンで分けて書いていら
                    れない(そもそもユーザー定義型に
                    も対応したい)




               11/12/13        関数型都市忘年会    33
What's the Template?
                    比較可能であることを表す、
Introduction
                ●
  What's
  Benefit           IComparableから派生したクラスの
How to use
Conclusion
                    変数だけを受け取って、仮想関数
                    compareで比較する?
                    ●
                          POD型に対応できない。
                    ●
                          比較するだけで仮想関数の仕組みを使わな
                          くてはいけないのは嬉しくない。




               11/12/13          関数型都市忘年会       34
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
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
What's the Benefit?




11/12/13         関数型都市忘年会        37
What's the Benefit?
                    テンプレートがあることで嬉しいこ
Introduction
                ●
  What's
  Benefit           とはなにか?
                    => テンプレートはコードの再利用
How to use
                ●
Conclusion

                    性を高める




               11/12/13        関数型都市忘年会    38
What's the Benefit?
                    テンプレートはクラスと関数の型を
Introduction
                ●
  What's
  Benefit           パラメータ化する仕組み
                    型をパラメータ化することで、クラ
How to use
                ●
Conclusion

                    スと関数を型と分離して書くことが
                    出来る。




               11/12/13        関数型都市忘年会    39
What's the Benefit?
                    型をパラメータ化したコンテナ
Introduction
                ●
  What's
  Benefit
How to use
                ●   std::vector, std::list, std::map,
Conclusion          std::queue, etc...
                ●   型がAssignableであるなど、いくつ
                    かの要件を満たすものであれば、何
                    でもこれらコンテナに渡すことが出
                    来る。



               11/12/13            関数型都市忘年会             40
What's the Benefit?
                    型をパラメータ化した関数
Introduction
                ●
  What's
  Benefit
How to use
                ●   std::min/max, std::swap, std::find,
Conclusion          std::sort, etc...
                ●   std::minとstd::maxは、型が
                    operator<で比較可能であれば、どん
                    な型でも使用することが出来る。
                    ●
                          operator<が定義されていなくても、比較関
                          数を指定するバージョンを使うこと
                          で、std::minを使用できる。


               11/12/13            関数型都市忘年会               41
What's the Benefit?
                    型をパラメータ化した関数
Introduction
                ●
  What's
  Benefit
How to use
                ●   std::min/max, std::swap, std::find,
Conclusion          std::sort, etc...
                ●   std::swapは、型がAssignableである
                    なら、どんな型でもswapに渡して使
                    うことが出来る。




               11/12/13            関数型都市忘年会               42
What's the Benefit?
                    型をパラメータ化した関数
Introduction
                ●
  What's
  Benefit
How to use
                ●   std::min/max, std::swap, std::find,
Conclusion          std::sort, etc...
                ●   std::find, std::sortなど
                ●   これらはSTLの`アルゴリズム'と呼ば
                    れる。




               11/12/13            関数型都市忘年会               43
What's the Benefit?
                    型をパラメータ化した関数
Introduction
                ●
  What's
  Benefit
How to use
                ●   std::min/max, std::swap, std::find,
Conclusion          std::sort, etc...
                ●   std::find, std::sortなど
                ●
                    イテレータという仕組みによって、
                    具体的なコンテナなどでなく、抽象
                    的な値の列(シーケンス)を扱えるよ
                    うになっている。

               11/12/13            関数型都市忘年会               44
What's the Benefit?
                    アルゴリズムは値の列を辿って何か
Introduction
                ●
  What's
  Benefit           したい
                    => コンテナなどを直接触らないで、
How to use
Conclusion      ●

                    イテレータと呼ばれる小さなクラス
                    に、コンテナから要素を参照する処
                    理を委譲。
                ●   => アルゴリズムは、イテレータをテ
                    ンプレートにすることで、イテレー
                    タの要件を満たす型を受け付けるよ
                    うにする。
               11/12/13        関数型都市忘年会    45
What's the Benefit?
                    => イテレータが用意出来れば、ど
Introduction
                ●
  What's
  Benefit
                    んなコンテナや、値の列であって
How to use
                    も、それをアルゴリズムに対して使
                    用できるようになる。
Conclusion


                    ●
                          ポインタもイテレータの要件を満たす
                    ●     というより、C++のイテレータは、ポインタ
                          を参考にして作られた。




               11/12/13          関数型都市忘年会     46
What's the Benefit?
                    プログラムの中にはたくさんのデー
Introduction
                ●
  What's
  Benefit           タ型と、たくさんのクラスと、たく
How to use
Conclusion
                    さんの関数がある。

                ●
                    とあるプログラムの中の
                    型の数をi、クラスの数をj、そしてア
                    ルゴリズムの数をkで表すとする。



               11/12/13        関数型都市忘年会    47
What's the Benefit?
                    それら全てに対応するプログラムを
Introduction
                ●
  What's
  Benefit           書くとすると、i * j * k個の組み合わ
How to use
Conclusion
                    せに対応しないといけない。




               11/12/13        関数型都市忘年会      48
What's the Benefit?
                    テンプレートを使って、
Introduction
                ●
  What's
  Benefit           ●
                          型とコンテナ、
How to use
Conclusion
                    ●
                          型とアルゴリズム、
                    ●
                          コンテナとアルゴリズム
                ●   を分離すれば、それぞれ、型をiだ
                    け、コンテナをjだけ、アルゴリズム
                    をkだけ用意すればいい。
                ●   つまりi + j + kで済む。


               11/12/13          関数型都市忘年会   49
What's the Benefit?
                    オブジェクト指向では継承によっ
Introduction
                ●
  What's
  Benefit           て、クラス定義を再利用することが
How to use
Conclusion
                    可能になった。
                ●   C++のテンプレートでは、型をパラ
                    メータ化することで、クラス定義の
                    再利用を可能にした。ついでにオブ
                    ジェクト指向では不可能だった、関
                    数の再利用も可能にした。



               11/12/13        関数型都市忘年会    50
What's the Benefit?
                    テンプレートを使うことで、ジェネ
Introduction
                ●
  What's
  Benefit           リックプログラミングが可能になっ
How to use
Conclusion
                    た。
                ●
                    ジェネリックプログラミング。
                ●
                    「型を決定していないクラスや関数
                    の断片を用意しておき、それらの組
                    み合わせでプログラミングをする」
                          (C++テンプレートテクニック 第一版 P.51)



               11/12/13            関数型都市忘年会           51
What's the Benefit?
                    テンプレートを使用して嬉しいこと
Introduction
                ●
  What's
  Benefit           は、これだけじゃない。
How to use
Conclusion

                ●
                    クラスがテンプレート化出来るとい
                    うことは、さらに重要な意味を持
                    つ。
                ●   => メタ関数
                ●   => Template Meta Programming


               11/12/13         関数型都市忘年会           52
What's the Benefit?
Introduction
  What's
                          template<class T>
                          template<class T>
  Benefit
                          struct add_const {
                          struct add_const {
How to use                    typedef T const type;
                              typedef T const type;
Conclusion                };
                          };
                ●
                    このようなクラステンプレートが
                    有ったときに、
                          add_const<int>::type
                          add_const<int>::type
                ●   という型はint constになる。
                    ●
                          charをテンプレート引数に渡せばchar const
                          に。std::stringならstd::string constに。
               11/12/13                関数型都市忘年会            53
What's the Benefit?
Introduction
  What's
                          template<class T>
                          template<class T>
  Benefit
                          struct add_const {
                          struct add_const {
How to use                    typedef T const type;
                              typedef T const type;
Conclusion                };
                          };


                ●   add_constに型を渡すと、型にconst
                    を修飾した型を得ることができる。




               11/12/13                関数型都市忘年会       54
What's the Benefit?
Introduction
  What's
                          template<class T>
                          template<class T>
  Benefit
                          struct add_pointer {
                          struct add_pointer {
How to use                   typedef T * type;
                             typedef T * type;
Conclusion                };
                          };
                ●
                    このようなクラステンプレートが
                    有ったときに、
                          add_pointer<int>::type
                          add_pointer<int>::type
                ●   という型はint *になる。
                    ●
                          charをテンプレート引数に渡せばchar *
                          に。std::stringならstd::string *に。
               11/12/13                関数型都市忘年会            55
What's the Benefit?
Introduction
  What's
                          template<class T>
                          template<class T>
  Benefit
                          struct add_pointer {
                          struct add_pointer {
How to use                   typedef T * type;
                             typedef T * type;
Conclusion                };
                          };


                ●   add_pointerに型を渡すと、型に*を
                    修飾した型を得ることが出来る。




               11/12/13                関数型都市忘年会   56
What's the Benefit?
Introduction

                    クラス名<テンプレート引数>::type
                    クラス名<テンプレート引数>::type
  What's
  Benefit
How to use
Conclusion      ●
                    クラス名を関数名、テンプレート引
                    数を引数、typeを戻り値の選択とい
                    う風に捉えると、関数のように考え
                    ることが出来る。




               11/12/13        関数型都市忘年会    57
What's the Benefit?
Introduction

                    クラス名<テンプレート引数>::type
                    クラス名<テンプレート引数>::type
  What's
  Benefit
How to use
Conclusion      ●
                    クラス名を関数名、テンプレート引
                    数を引数、typeを戻り値の選択とい
                    う風に捉えると、関数のように考え
                    ることが出来る。
                ●
                    通常の関数と違い、型に関する操作
                    が基本。
                ●   => Template Meta Programming

               11/12/13        関数型都市忘年会        58
What's the Benefit?
                    これをこじらせると^H^H^H^H^H^H
Introduction
                ●
  What's
  Benefit
                    発展させるとどうなるか
How to use
Conclusion




               11/12/13        関数型都市忘年会    59
What's the Template?
namespace mpl = boost::mpl;
typedef
    mpl::vector<int, std::string, user_defined_type>
seq1;
typedef
    mpl::list<int, std::string, user_defined_type>
seq2;

// mpl::equal は、Sequence の比較を行う
BOOST_MPL_ASSERT((mpl::equal< seq1, seq2 >));
//型のシーケンス(コンパイル時データ構造)を作って、そ
の要素(型が要素!)を比較

11/12/13              関数型都市忘年会                    60
What's the Benefit?
                    これをこじらせると^H^H^H^H^H^H
Introduction
                ●
  What's
  Benefit
                    発展させるとどうなるか
How to use
Conclusion      ●
                    こんなものも
                ●   http://d.hatena.ne.jp/tarao/20111101/
                    1320143278
                    「C++のテンプレートでラムダ計算
                    と型推論」



               11/12/13           関数型都市忘年会              61
What's the Benefit?
                    その他、テンプレートを使うことで
Introduction
                ●
  What's
  Benefit           可能になる、便利なテクニック
How to use
Conclusion
                    ●
                          ポリシークラス
                          –   クラスの挙動をテンプレートで差し替える
                    ●
                          パラメータ化継承
                          –   継承関係をテンプレートで差し替える
                    ●
                          CRTP
                          –   静的多態
                    ●
                          タグディスパッチ
                          –   静的オーバーロード
                    ●     SFINAE
                          –   静的オーバーロード
               11/12/13              関数型都市忘年会       62
What's the Benefit?
                    ポリシークラス
Introduction
                ●
  What's

                    クラスの挙動をテンプレートで差し
  Benefit
                ●

                    替える
How to use
Conclusion




               11/12/13        関数型都市忘年会    63
What's the Benefit?
template<class Policy>
struct logger
{
    //なんかいろいろなコンストラクタなど

      void output(char const *msg) {
          Policy::output(msg);
      }

      //なんかいろいろなメンバ関数
};


11/12/13                関数型都市忘年会       64
What's the Benefit?
strict cout_policy
{
    static void output(char const *msg) {
        std::cout << msg << std::endl;
    }
};
struct debugger_policy
{
    static void output(char const *msg ) {
       OutputDebugString(msg);
    }
};

11/12/13              関数型都市忘年会               65
What's the Benefit?
                    ポリシークラス
Introduction
                ●
  What's
  Benefit
How to use                void function_to_be_logged()
                          void function_to_be_logged()
Conclusion                {
                          {
                              logger<cout_policy> lg;
                              logger<cout_policy> lg;
                              lg.output("logging message");
                              lg.output("logging message");
                          }
                          }
                ●
                    標準出力にログが吐き出される



               11/12/13                 関数型都市忘年会              66
What's the Benefit?
                    ポリシークラス
Introduction
                ●
  What's
  Benefit
How to use                void function_to_be_logged()
                          void function_to_be_logged()
Conclusion                {
                          {
                              logger<debugger_policy> lg;
                              logger<debugger_policy> lg;
                              lg.output("logging message");
                              lg.output("logging message");
                          }
                          }
                ●
                    デバッグ出力にログが吐き出される



               11/12/13                 関数型都市忘年会              67
What's the Benefit?
Introduction
  What's
                ●   loggerを継承したりすることな
  Benefit
                    く、loggerの挙動を変更することが
                    出来る
How to use
Conclusion




               11/12/13        関数型都市忘年会    68
What's the Benefit?
Introduction
  What's
                ●   loggerは受け取りたいポリシーに
  Benefit
                    outputという名前のstaticメンバ関数
                    があることだけしか要求していない
How to use
Conclusion


                //自分で定義した、
                //自分で定義した、
                //outputスタティックメンバ関数を持つクラス
                //outputスタティックメンバ関数を持つクラス
                struct my_logger_policy;
                struct my_logger_policy;

                ●   こんなクラスもloggerのポリシーに
                    渡すことが出来る。

               11/12/13        関数型都市忘年会     69
What's the Benefit?
Introduction
  What's
                ●   policyはloggerが必要とする要件にし
  Benefit
                    か依存していない。
How to use
Conclusion      ●   loggerもpolicyに求める要件の実装に
                    しか依存していない。
                ●   Non-Intrusive:非侵入的
                ●   「トリから始まるnon-intrusiveness談義
                          http://togetter.com/li/33641




               11/12/13                 関数型都市忘年会         70
What's the Benefit?
                    その他、テンプレートを使うことで
Introduction
                ●
  What's
  Benefit           可能になる、便利なテクニック
                    多分ここらへんが聞いてて一番面白
How to use
                ●
Conclusion

                    くなるはずのところですが残念なが
                    ら資料ができていませんごめんなさ
                    い。




               11/12/13        関数型都市忘年会    71
How to use the Template.




11/12/13            関数型都市忘年会          72
How to use the Template.
                    テンプレートの使い方/書き方
Introduction
                ●
  What's

                          クラステンプレート
  Benefit
                    ●
How to use
Conclusion          ●
                          関数テンプレート




               11/12/13          関数型都市忘年会   73
How to use the Template.
                    クラステンプレートの使い方
Introduction
                ●
  What's
  Benefit
How to use
Conclusion




               11/12/13     関数型都市忘年会      74
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
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
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
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
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
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
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
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
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
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
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
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
How to use the Template.
                    関数テンプレートの使い方
Introduction
                ●
  What's
  Benefit
How to use
Conclusion




               11/12/13     関数型都市忘年会      87
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
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
How to use the Template.
                    関数テンプレートの使い方
Introduction
                ●
  What's

                    引数からテンプレートの型が推論で
  Benefit
                ●

                    きる場合は、テンプレート引数を指
How to use
Conclusion

                    定する必要はない。




               11/12/13     関数型都市忘年会      90
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
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
Conclusion




11/12/13     関数型都市忘年会   93
Conclusion
Introduction
  What's
                ●   C++のテンプレートはとても便利
  Benefit
                    で、実行時効率を損なうこと無く、
How to use
                    柔軟で再利用性の高いコードを書く
                    ことが出来る仕組みです。
Conclusion




               11/12/13         関数型都市忘年会   94
Conclusion
Introduction
  What's
                ●   C++11になって、C++のテンプレー
  Benefit
                    トはより便利になります(可変長テン
                    プレートなど)
How to use
Conclusion

                ●   普段C++を使っていて、テンプレー
                    トをあまり使ったことがない人がい
                    たら、ぜひテンプレートに手を出し
                    てみてはいかがでしょうか。




               11/12/13         関数型都市忘年会   95
Conclusion
                    参考文献/サイト
Introduction
                ●
  What's
  Benefit           ●
                          「C++リファレンスマニュアル」
How to use
Conclusion
                            アジソンウェスレイ
                    ●
                          「C++の設計と進化」
                            ソフトバンクパブリッシング
                    ●     「C++テンプレートテクニック」
                            ソフトバンククリエイティブ
                    ●     「C++テンプレートメタプログラミング」
                             翔泳社
                    ●     http://www.cplusplus.com/
                    ●     http://www.sgi.com/tech/stl/index.html

               11/12/13                   関数型都市忘年会                 96
Thank You!
           ありがとうございました!



11/12/13       関数型都市忘年会   97
ちなみに。
                    この資料でやり残してること。
Introduction
                ●
  What's
  Benefit
How to use
                    ●     typenameキーワード
Conclusion
                    ●     template限定子
                    ●     CRTPなどの紹介
                    ●
                          関数テンプレートの使い方と型推
                          論の紹介




               11/12/13        関数型都市忘年会     98

C++ template-primer

  • 1.
    C++ テンプレート入門 @hotwatermorning 11/12/13 関数型都市忘年会 1
  • 2.
    自己紹介 ● @hotwatermorning ● C++でプログラム書いてます。 11/12/13 関数型都市忘年会 2
  • 3.
    自己紹介 ● Boost.勉強会 #6 札幌を開催しました! 11/12/13 関数型都市忘年会 3
  • 4.
    Introduction 11/12/13 関数型都市忘年会 4
  • 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
  • 8.
    What's the Template? 11/12/13 関数型都市忘年会 8
  • 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? #definestackdeclare(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
  • 12.
    What's the Template? #definestackimplement(TYPE) stack(TYPE)::stack(TYPE)(int n) { min_ = top_ = new TYPE(n); max_ = min_ + n; } stack(TYPE)::~stack(TYPE)() { delete[] min_; } void stack(TYPE)::push(TYPE x) { assert(top_ != min_); *top_++ = x; } こんな感じで行を結合しながら書いていく・・・ 11/12/13 関数型都市忘年会 12
  • 13.
    What's the Template? #definename2(X,Y) X/**/Y => トークンペーストマクロ => 現在の仕様では X##Yとする #define declare(CLASS,TYPE) name2(CLASS,declare)(TYPE) #define implement(CLASS,TYPE) name2(CLASS,implement)(TYPE) #define stack(TYPE) name2(stack,TYPE) 11/12/13 関数型都市忘年会 13
  • 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? #definemul2(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<classT> 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
  • 28.
    What's the Template? こんな感じで使えるという例 Introduction ● What's Benefit How to use //int型の要素を持つvectorクラス //int型の要素を持つvectorクラス Conclusion std::vector<int> is; std::vector<int> is; //char型の要素を持つvectorクラス //char型の要素を持つvectorクラス std::vector<char> cs; std::vector<char> cs; //std::string型の要素をもつvectorクラス //std::string型の要素をもつvectorクラス std::vector<std::string> ss; std::vector<std::string> ss; //なんらかのユーザー定義型を要素に持つ //なんらかのユーザー定義型を要素に持つ //vectorクラス //vectorクラス std::vector<SomeUserDefinedType> us; std::vector<SomeUserDefinedType> us; 11/12/13 関数型都市忘年会 28
  • 29.
    What's the Template? こんな感じで使えるという例 Introduction ● What's Benefit How to use is.size(); is.size(); Conclusion cs.size(); cs.size(); ss.size(); ss.size(); us.size(); us.size(); ● 全部使い方一緒! 11/12/13 関数型都市忘年会 29
  • 30.
    What's the Template? こんな感じで使えるという例 Introduction ● What's Benefit How to use is.front(); //(int &) is.front(); //(int &) cs.front(); //(char &) cs.front(); //(char &) Conclusion ss.front(); //(std::string &) ss.front(); //(std::string &) us.front(); //(SomeUserDefinedType &) us.front(); //(SomeUserDefinedType &) ● それぞれ指定した型で要素を取得で きる!! 11/12/13 関数型都市忘年会 30
  • 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
  • 37.
    What's the Benefit? 11/12/13 関数型都市忘年会 37
  • 38.
    What's the Benefit? テンプレートがあることで嬉しいこ Introduction ● What's Benefit とはなにか? => テンプレートはコードの再利用 How to use ● Conclusion 性を高める 11/12/13 関数型都市忘年会 38
  • 39.
    What's the Benefit? テンプレートはクラスと関数の型を Introduction ● What's Benefit パラメータ化する仕組み 型をパラメータ化することで、クラ How to use ● Conclusion スと関数を型と分離して書くことが 出来る。 11/12/13 関数型都市忘年会 39
  • 40.
    What's the Benefit? 型をパラメータ化したコンテナ Introduction ● What's Benefit How to use ● std::vector, std::list, std::map, Conclusion std::queue, etc... ● 型がAssignableであるなど、いくつ かの要件を満たすものであれば、何 でもこれらコンテナに渡すことが出 来る。 11/12/13 関数型都市忘年会 40
  • 41.
    What's the Benefit? 型をパラメータ化した関数 Introduction ● What's Benefit How to use ● std::min/max, std::swap, std::find, Conclusion std::sort, etc... ● std::minとstd::maxは、型が operator<で比較可能であれば、どん な型でも使用することが出来る。 ● operator<が定義されていなくても、比較関 数を指定するバージョンを使うこと で、std::minを使用できる。 11/12/13 関数型都市忘年会 41
  • 42.
    What's the Benefit? 型をパラメータ化した関数 Introduction ● What's Benefit How to use ● std::min/max, std::swap, std::find, Conclusion std::sort, etc... ● std::swapは、型がAssignableである なら、どんな型でもswapに渡して使 うことが出来る。 11/12/13 関数型都市忘年会 42
  • 43.
    What's the Benefit? 型をパラメータ化した関数 Introduction ● What's Benefit How to use ● std::min/max, std::swap, std::find, Conclusion std::sort, etc... ● std::find, std::sortなど ● これらはSTLの`アルゴリズム'と呼ば れる。 11/12/13 関数型都市忘年会 43
  • 44.
    What's the Benefit? 型をパラメータ化した関数 Introduction ● What's Benefit How to use ● std::min/max, std::swap, std::find, Conclusion std::sort, etc... ● std::find, std::sortなど ● イテレータという仕組みによって、 具体的なコンテナなどでなく、抽象 的な値の列(シーケンス)を扱えるよ うになっている。 11/12/13 関数型都市忘年会 44
  • 45.
    What's the Benefit? アルゴリズムは値の列を辿って何か Introduction ● What's Benefit したい => コンテナなどを直接触らないで、 How to use Conclusion ● イテレータと呼ばれる小さなクラス に、コンテナから要素を参照する処 理を委譲。 ● => アルゴリズムは、イテレータをテ ンプレートにすることで、イテレー タの要件を満たす型を受け付けるよ うにする。 11/12/13 関数型都市忘年会 45
  • 46.
    What's the Benefit? => イテレータが用意出来れば、ど Introduction ● What's Benefit んなコンテナや、値の列であって How to use も、それをアルゴリズムに対して使 用できるようになる。 Conclusion ● ポインタもイテレータの要件を満たす ● というより、C++のイテレータは、ポインタ を参考にして作られた。 11/12/13 関数型都市忘年会 46
  • 47.
    What's the Benefit? プログラムの中にはたくさんのデー Introduction ● What's Benefit タ型と、たくさんのクラスと、たく How to use Conclusion さんの関数がある。 ● とあるプログラムの中の 型の数をi、クラスの数をj、そしてア ルゴリズムの数をkで表すとする。 11/12/13 関数型都市忘年会 47
  • 48.
    What's the Benefit? それら全てに対応するプログラムを Introduction ● What's Benefit 書くとすると、i * j * k個の組み合わ How to use Conclusion せに対応しないといけない。 11/12/13 関数型都市忘年会 48
  • 49.
    What's the Benefit? テンプレートを使って、 Introduction ● What's Benefit ● 型とコンテナ、 How to use Conclusion ● 型とアルゴリズム、 ● コンテナとアルゴリズム ● を分離すれば、それぞれ、型をiだ け、コンテナをjだけ、アルゴリズム をkだけ用意すればいい。 ● つまりi + j + kで済む。 11/12/13 関数型都市忘年会 49
  • 50.
    What's the Benefit? オブジェクト指向では継承によっ Introduction ● What's Benefit て、クラス定義を再利用することが How to use Conclusion 可能になった。 ● C++のテンプレートでは、型をパラ メータ化することで、クラス定義の 再利用を可能にした。ついでにオブ ジェクト指向では不可能だった、関 数の再利用も可能にした。 11/12/13 関数型都市忘年会 50
  • 51.
    What's the Benefit? テンプレートを使うことで、ジェネ Introduction ● What's Benefit リックプログラミングが可能になっ How to use Conclusion た。 ● ジェネリックプログラミング。 ● 「型を決定していないクラスや関数 の断片を用意しておき、それらの組 み合わせでプログラミングをする」 (C++テンプレートテクニック 第一版 P.51) 11/12/13 関数型都市忘年会 51
  • 52.
    What's the Benefit? テンプレートを使用して嬉しいこと Introduction ● What's Benefit は、これだけじゃない。 How to use Conclusion ● クラスがテンプレート化出来るとい うことは、さらに重要な意味を持 つ。 ● => メタ関数 ● => Template Meta Programming 11/12/13 関数型都市忘年会 52
  • 53.
    What's the Benefit? Introduction What's template<class T> template<class T> Benefit struct add_const { struct add_const { How to use typedef T const type; typedef T const type; Conclusion }; }; ● このようなクラステンプレートが 有ったときに、 add_const<int>::type add_const<int>::type ● という型はint constになる。 ● charをテンプレート引数に渡せばchar const に。std::stringならstd::string constに。 11/12/13 関数型都市忘年会 53
  • 54.
    What's the Benefit? Introduction What's template<class T> template<class T> Benefit struct add_const { struct add_const { How to use typedef T const type; typedef T const type; Conclusion }; }; ● add_constに型を渡すと、型にconst を修飾した型を得ることができる。 11/12/13 関数型都市忘年会 54
  • 55.
    What's the Benefit? Introduction What's template<class T> template<class T> Benefit struct add_pointer { struct add_pointer { How to use typedef T * type; typedef T * type; Conclusion }; }; ● このようなクラステンプレートが 有ったときに、 add_pointer<int>::type add_pointer<int>::type ● という型はint *になる。 ● charをテンプレート引数に渡せばchar * に。std::stringならstd::string *に。 11/12/13 関数型都市忘年会 55
  • 56.
    What's the Benefit? Introduction What's template<class T> template<class T> Benefit struct add_pointer { struct add_pointer { How to use typedef T * type; typedef T * type; Conclusion }; }; ● add_pointerに型を渡すと、型に*を 修飾した型を得ることが出来る。 11/12/13 関数型都市忘年会 56
  • 57.
    What's the Benefit? Introduction クラス名<テンプレート引数>::type クラス名<テンプレート引数>::type What's Benefit How to use Conclusion ● クラス名を関数名、テンプレート引 数を引数、typeを戻り値の選択とい う風に捉えると、関数のように考え ることが出来る。 11/12/13 関数型都市忘年会 57
  • 58.
    What's the Benefit? Introduction クラス名<テンプレート引数>::type クラス名<テンプレート引数>::type What's Benefit How to use Conclusion ● クラス名を関数名、テンプレート引 数を引数、typeを戻り値の選択とい う風に捉えると、関数のように考え ることが出来る。 ● 通常の関数と違い、型に関する操作 が基本。 ● => Template Meta Programming 11/12/13 関数型都市忘年会 58
  • 59.
    What's the Benefit? これをこじらせると^H^H^H^H^H^H Introduction ● What's Benefit 発展させるとどうなるか How to use Conclusion 11/12/13 関数型都市忘年会 59
  • 60.
    What's the Template? namespacempl = boost::mpl; typedef mpl::vector<int, std::string, user_defined_type> seq1; typedef mpl::list<int, std::string, user_defined_type> seq2; // mpl::equal は、Sequence の比較を行う BOOST_MPL_ASSERT((mpl::equal< seq1, seq2 >)); //型のシーケンス(コンパイル時データ構造)を作って、そ の要素(型が要素!)を比較 11/12/13 関数型都市忘年会 60
  • 61.
    What's the Benefit? これをこじらせると^H^H^H^H^H^H Introduction ● What's Benefit 発展させるとどうなるか How to use Conclusion ● こんなものも ● http://d.hatena.ne.jp/tarao/20111101/ 1320143278 「C++のテンプレートでラムダ計算 と型推論」 11/12/13 関数型都市忘年会 61
  • 62.
    What's the Benefit? その他、テンプレートを使うことで Introduction ● What's Benefit 可能になる、便利なテクニック How to use Conclusion ● ポリシークラス – クラスの挙動をテンプレートで差し替える ● パラメータ化継承 – 継承関係をテンプレートで差し替える ● CRTP – 静的多態 ● タグディスパッチ – 静的オーバーロード ● SFINAE – 静的オーバーロード 11/12/13 関数型都市忘年会 62
  • 63.
    What's the Benefit? ポリシークラス Introduction ● What's クラスの挙動をテンプレートで差し Benefit ● 替える How to use Conclusion 11/12/13 関数型都市忘年会 63
  • 64.
    What's the Benefit? template<classPolicy> struct logger { //なんかいろいろなコンストラクタなど void output(char const *msg) { Policy::output(msg); } //なんかいろいろなメンバ関数 }; 11/12/13 関数型都市忘年会 64
  • 65.
    What's the Benefit? strictcout_policy { static void output(char const *msg) { std::cout << msg << std::endl; } }; struct debugger_policy { static void output(char const *msg ) { OutputDebugString(msg); } }; 11/12/13 関数型都市忘年会 65
  • 66.
    What's the Benefit? ポリシークラス Introduction ● What's Benefit How to use void function_to_be_logged() void function_to_be_logged() Conclusion { { logger<cout_policy> lg; logger<cout_policy> lg; lg.output("logging message"); lg.output("logging message"); } } ● 標準出力にログが吐き出される 11/12/13 関数型都市忘年会 66
  • 67.
    What's the Benefit? ポリシークラス Introduction ● What's Benefit How to use void function_to_be_logged() void function_to_be_logged() Conclusion { { logger<debugger_policy> lg; logger<debugger_policy> lg; lg.output("logging message"); lg.output("logging message"); } } ● デバッグ出力にログが吐き出される 11/12/13 関数型都市忘年会 67
  • 68.
    What's the Benefit? Introduction What's ● loggerを継承したりすることな Benefit く、loggerの挙動を変更することが 出来る How to use Conclusion 11/12/13 関数型都市忘年会 68
  • 69.
    What's the Benefit? Introduction What's ● loggerは受け取りたいポリシーに Benefit outputという名前のstaticメンバ関数 があることだけしか要求していない How to use Conclusion //自分で定義した、 //自分で定義した、 //outputスタティックメンバ関数を持つクラス //outputスタティックメンバ関数を持つクラス struct my_logger_policy; struct my_logger_policy; ● こんなクラスもloggerのポリシーに 渡すことが出来る。 11/12/13 関数型都市忘年会 69
  • 70.
    What's the Benefit? Introduction What's ● policyはloggerが必要とする要件にし Benefit か依存していない。 How to use Conclusion ● loggerもpolicyに求める要件の実装に しか依存していない。 ● Non-Intrusive:非侵入的 ● 「トリから始まるnon-intrusiveness談義 http://togetter.com/li/33641 11/12/13 関数型都市忘年会 70
  • 71.
    What's the Benefit? その他、テンプレートを使うことで Introduction ● What's Benefit 可能になる、便利なテクニック 多分ここらへんが聞いてて一番面白 How to use ● Conclusion くなるはずのところですが残念なが ら資料ができていませんごめんなさ い。 11/12/13 関数型都市忘年会 71
  • 72.
    How to usethe Template. 11/12/13 関数型都市忘年会 72
  • 73.
    How to usethe Template. テンプレートの使い方/書き方 Introduction ● What's クラステンプレート Benefit ● How to use Conclusion ● 関数テンプレート 11/12/13 関数型都市忘年会 73
  • 74.
    How to usethe Template. クラステンプレートの使い方 Introduction ● What's Benefit How to use Conclusion 11/12/13 関数型都市忘年会 74
  • 75.
    How to usethe 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 usethe 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 usethe 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 usethe 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 usethe 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 usethe 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 usethe 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 usethe 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 usethe 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 usethe 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 usethe 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 usethe 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 usethe Template. 関数テンプレートの使い方 Introduction ● What's Benefit How to use Conclusion 11/12/13 関数型都市忘年会 87
  • 88.
    How to usethe 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 usethe 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 usethe Template. 関数テンプレートの使い方 Introduction ● What's 引数からテンプレートの型が推論で Benefit ● きる場合は、テンプレート引数を指 How to use Conclusion 定する必要はない。 11/12/13 関数型都市忘年会 90
  • 91.
    How to usethe 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 usethe 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
  • 93.
    Conclusion 11/12/13 関数型都市忘年会 93
  • 94.
    Conclusion Introduction What's ● C++のテンプレートはとても便利 Benefit で、実行時効率を損なうこと無く、 How to use 柔軟で再利用性の高いコードを書く ことが出来る仕組みです。 Conclusion 11/12/13 関数型都市忘年会 94
  • 95.
    Conclusion Introduction What's ● C++11になって、C++のテンプレー Benefit トはより便利になります(可変長テン プレートなど) How to use Conclusion ● 普段C++を使っていて、テンプレー トをあまり使ったことがない人がい たら、ぜひテンプレートに手を出し てみてはいかがでしょうか。 11/12/13 関数型都市忘年会 95
  • 96.
    Conclusion 参考文献/サイト Introduction ● What's Benefit ● 「C++リファレンスマニュアル」 How to use Conclusion アジソンウェスレイ ● 「C++の設計と進化」 ソフトバンクパブリッシング ● 「C++テンプレートテクニック」 ソフトバンククリエイティブ ● 「C++テンプレートメタプログラミング」 翔泳社 ● http://www.cplusplus.com/ ● http://www.sgi.com/tech/stl/index.html 11/12/13 関数型都市忘年会 96
  • 97.
    Thank You! ありがとうございました! 11/12/13 関数型都市忘年会 97
  • 98.
    ちなみに。 この資料でやり残してること。 Introduction ● What's Benefit How to use ● typenameキーワード Conclusion ● template限定子 ● CRTPなどの紹介 ● 関数テンプレートの使い方と型推 論の紹介 11/12/13 関数型都市忘年会 98