C++の基礎 - テンプレート

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
ナビゲーションに移動 検索に移動

概要

C++には多くのデータ型が存在する。
int型やdouble型、char型、std::string型など、自作のデータ型も含めれば無数に存在する。

型というのは不自由なもので、型を決定することで、そのコード自体を不自由にしてしまう可能性がある。

オーバーロード機能を使えば同名で多重定義することも可能であるが、型は無数に存在するので無数に記述しなければならい。
また、オーバーロード機能を使用する場合、開発者はユーザがどのような型を使用するのか予知する必要がある。


関数テンプレート

開発者は、様々な型に対して適応できるコードで記述する必要がある。
以下のソースコードは、様々な型の加算ができる関数である。
この関数の場合、+演算子を使用できない型はコンパイル時にエラーが出力される。

 template<typename T>
 T Add(T a, T b)
 {
    return a + b;
 }
 
 // 2つ以上の引数を取ることもできる
 // T = UまたはT ≠ Uであってもこの関数が使用できる
 template<typename T, typename U>
 T Add(T a,U b)
 {
    return a + b;
 }


また、template<class T>と記述することで、Tを任意の型として関数内で使用できる。


テンプレートの特殊化

テンプレートには、特定の型だけ異なる処理を行うテンプレートの特殊化の機能がある。

 template <typename T>
 T add(T a,T b)
 {
    return a + b;
 }
 
 // double型だけ異なる処理を行う
 template <>
 double add(double a, double b)
 {
    return a - b;
 }



関数クラスメンバエイリアステンプレート

以下に示す通り、テンプレートは数種類が存在する。

  • 関数テンプレート
  • クラステンプレート
  • メンバテンプレート
  • エイリアステンプレート


関数テンプレート
 template <typename T>
 T add(T a, T b)
 {
    return a + b;
 }


クラステンプレート

宣言方法は、下記のようにすると、テンプレート引数に指定した型を持つようになる。

 CMyClass<int> clsHoge();  // テンプレートクラスのインスタンス生成
 template <typename T>
 class CMyClass
 {
    public:
       CMyClass() {};
       virtual ~CMyClass() {};
       T value;
 };


メンバテンプレート

任意のメンバ関数にだけ関数テンプレートを使用することもできる。
定義方法は、関数テンプレートとほぼ同じである。

 class CMyClass
 {
    public:
       int nanika;
 
    public:
       template<typename T>
       T Function(T a,T b);
 };


エイリアステンプレート

C++11から、typedefをusingで記述できるようになった。
以下の2つは同様の意味を持つ。

 typedef TypographicError typo;
 using typo = TypographicError;


また、usingを用いたエイリアスにはテンプレートを使用することができる。
このように、型のエイリアスの作成、テンプレート引数の再編成などが行える。

 UsingTemplate.cpp
 template<typename T, typename U>
 T Add1(T a, U b);
 
 template<typename T>
 using Add2 = Add1<T, T>;