■ Template する場所を見抜く方法
    [ 処理が同じ ]で [ Data 型が異なる ]ところ.       
     -> 逆に関数とは, 特定の処理をひとくくりにすること. 
    Instanciate した時点で既に, template ではないことに注目. 
    次のような記述もえきる。
     struct Tbl
     {
       string name;
       void *(*create)();
     }; 
    Tbl tbl[] = {
      {
        {"Chara", create<  Chara > }, 
      }
    int swap( int &a, int &b ) {
      int t = a;
      a = b;
      b = t;
    }
    float swap( float &a, float &b ) {
      float t = a;
      a = b;
      b = t;
    }
    template < typename T>
    void swap( T& a, T& b )
    {
        T t = a; 
        a = b; 
        b = t;
    }  
    swap(x, y);      // コンパイラが自動で生成する。
    swap< int>(x, y); // 型を明示する場合は int をつける。
■ 関数テンプレート(FunctionTemplate)
  SYNTAX
    [ class | typename ] keyword 利用する。
    template < class type> 
    function-declarator
    template < typename type> 
    function-declarator
    template < class X1 , class X2> 
    void println(X1 var1 , X2 var2);
    関数テンプレートには2種類の場所で定義できる。
  
  // template 型であることの宣言
  template<  class T >   
  T myabs( T a ){
      a = a>0 ? a : -a;
  }
      
  // 使用するときは
  int b = -7;
  int n = myabs( b );
  // 明示する
  int b = -7;
  int n = myabs< int>( b );
    template<  class T1, class T2 >
    T1 Add( T1 a, T2 b ){
      return a+b;
    }  
      int a = 5;
      char b = 3;
      int n = add( a, b );
■ クラステンプレート(ClassTemplate)
  DESC
    意味としては、クッキーの型だと思えばOK 
    素材( 型 )と処理を分離して考える
    内部的な型だけを変換していると思えばOK , あくまでクラス定義しているにすぎない
    次のように考えるとわかりやすい 
    template<  XXX > を除去
    2. XXX -> 具体的な型に変換
    [ vector ] を例に考えてみる. 
      vector<  myInt > foo;   // int 型 vec ( 使用する際は, < 型> とする )
      
      template < T> 
      class vector{
         T foo;
      }
■ 型だけでなく 値もパラメータとして受け取れる
    非型パラメータを指定する場合は型名は実際の型にする。
    // 固定サイズの配列
    template < typename T, int N>
    class Array {
      public:
        void push_back( const T &data ) {
          data[ p ] = data;
          p ++;
        }
        Array() : p(0){}
      private:
        T data[N];
        int p;
     };
    // int 型 10 要素の固定配列
    Array< int, 10> a;
    a.push_back( 5 );
//
// unsigned にすることで,負数を避けることが可能. 
// アラインメントをそろえる
      template<  unsigned int BASE, typename T >  
      T floor( T x ) 
      {
        return static_cast< T>( ((x) + ((BASE)-1)) & ~((BASE)-1) );
      }
    // 利用する時は
    roundUp< 16>( 10 );
■ テンプレートパラメータにデフォルト値を設定する
    デフォルト値を指定するには、デフォルト引数と同様に = TYPE とする。
    STL クラスはアロケータのデフォルトとして std::allocator< T> をもつ。
      template < class T, class Allocator = allocator< T> >
      class vector
      {
        ...
      }
    class MyAllocator {
    };
    vector<  int, MyAllocator > v;
■ template 化するコンパイラの立場で考えてみる
  template < class T>     // 以下は汎用クラスだよ. ( 未知の型がくるよ. とりあえず T にするよ )
template <  [typelist] [ , [ arglist]] > declaration
    パラメータ化した汎用関数、または汎用クラスだよー と compiler に通知. 
  declaration : 関数またはクラスを宣言
  
typename nameType
    未知の識別子の[ 型 ]だよ- とコンパイラに通知( class keyword でも OK )
■ 特殊化する
  DESC
    ある特定のテンプレート型の場合だけ特別仕様にする時につかう。
    
    特定の template 引数用に定義すること. 
         -> 特殊化する前に、汎用 template を定義する必要あり
    XXX 型の場合の特別バージョンという意味。
    template< >   
    void func<  XXX >{} 
           // 基本は CMP 単位で処理されて, 
           // あ !  foo という FunctionTemplate があるな... 
           template <  typename T > T foo();
           // これは float 型の場合に利用する関数だな...
           template < > 
           float foo< float>()
           {
             float data = 0.0f;
             printf("special");
             return data;
           }            
           Client::main() {
              // foo はたしか, FunctionTemplate で float 型の特殊定義があったな... 
              // よし今回はこれを使おう. 
              foo<  float >();
           }
       template < typename T>
       void copy(T* dst, const T* src, size_t size)
       {
         for(size_t i = 0; i <  size; i++) {
           dst[i] = src[i];
         }
       }
■ template 全般
    Class, 関数の定義をパラメータ化する ( Java にない便利機能 )
    定義を抽象化( Grouping )する.
    通常は. 宣言と定義を header にする。
    宣言のみでは LINK できない。
    コンパイル時にコードを生成するため、コンパイル単位で定義が必要になるため。
    基本的に define 同様の置換がされるが, 
    PreProcessor ではなくコンパイラがコードを生成する
    汎用 class( 型 )だけでなく, 固定型も使用可能. 
     = をつけると Default 設定. ( = とでてきたら Default で [い.く.つ] と考えること )
    実際に使用して == ( PrmTpl )を与えて, 評価されるらしい. 
   //  MethodTemplate も作成できる
      class Foo {
       public:
        template<  typename T >
        void func( T i ) 
        {
         cout < <  i < <  endl;
        }
      }; 
      
      foo.func( 10.0f );
      foo.func( 10 );
      foo.func( "10" );
     class Object {
        // ctor という Method を template 化した
        template<  typename T >
        Object( T ty ){ ... }  
     };
     int i;     
     Object o( i );
       // SmartPtr を 実装.
       class Resource
       {
   public:
     void use(){ /*参照カウンタ+1*/ }
     void release(){ /*参照カウンタ-1と解放*/ }
       };
       template < class T>
       class SmartPointer
       {
   T *m_pointer;   // 本体.
        public:
   // INIT
   SmartPointer(T *p)
     :m_pointer(p) {
   {
       // 置換した状態で矛盾があれば CmpErr
       m_pointer->use();
   }
   ~SmartPointer() {
     m_pointer->release();
   }
       }
■ template 具体例
  DESC
     setter, getter の template 化
      
  // prop object
  template < class T>     // 以下は汎用クラスだよ. ( 未知の型がくるよ. とりあえず T という名前にするよ  ^/ )
  class typeProp : public absProp
  {
    public:
      virtual eProp getType() const;
      // accessor という処理は同じ. 
      vitual T getVal( base *p ) = 0;
      vitual void setVal( base *p, T val ) = 0;
  };
■ 色々実験してみる
   Q: PrmTpl を引数にとらない関数は FuncTemplate にできるか ? 
     template<  typename T >
     void func()
     {
       T i = 20;
       printf( i );
     }     
     func< int>();     // OK: 文として矛盾が起きないなら問題なし. 
     func();          // ERR: TemplateParamter がわからない.  
         <  T > と教えてあげる.  
     func<  Foo >();   // ERR: ここで本当に instantiated しているらしい.
     Foo i = 20;      // ERR 
     func();          // ERROR: no matching function for call to `func()' func が具体化されていいない証拠. 
■ refcnt : 参照カウンタ 
  DESC
    object 自身が他から, 参照される個数をカウントする. 
     0 になれば, 不要ということで解放. -> new した時点で 1.
  POINT
    2. create() 作成 && release() 破棄
    3. Model から参照されている際に、削除できないようにリソースという扱いにしている
    ( ie. new, delete < -> create(), release() なんだ  )
    4. mdl->release() は mdl というポインタ( 矢印 )から Object(Resource)を離すイメージ 
    // delete のかわり、[ 参.照.し.な.い.よ ] と宣言. 
    virtual void release(){
      counter --;
    if ( counter == 0 ){
      delete this;
    }
    }    
    // これを呼ばないとだめなのが, メンドイ. 
    void use(){
      counter ++;
    }
    // 作成時に cnt = 1
    Resource() : m_counter(1), m_name(0) {
    }
  WARNING 
      obj が相互に 参照する場合は, 循環がおき, mem leak がおきるので注意
    任意の数値を文字列に変換する関数テンプレート。
    #include < iostream>
    #include < string>
    #include < sstream>
    template< class T> 
    string numberToString(T n)
    {
        stringstream s;
        s < <  n;
        return ss.str();
    }