先頭へ戻る

関数テンプレート | Programming Place Plus 用語集

Programming Place Plus トップページ用語集

先頭へ戻る

名称

解説

C++ や D言語のテンプレートと呼ばれる機能のうち、関数の雛形となるもののことです。

テンプレートは、静的型付け言語において、を抽象化したソースコードを記述するための機能です。

関数テンプレートは、関数の仮引数戻り値の型を抽象化し、ソースコードを共通化します。たとえば、与えられた2つののうち、大きい方を返す max関数を、C++ の関数テンプレートで記述すると、次のようになります。

template <typename T>    // テンプレートであることを示す記述
T max(T a, T b)          // 具体的な型の代わりに T を使う
{
    return a >= b ? a : b;
}

int のような具体的な型の指定の代わりに T という型名を使うことで抽象化しています。この T はテンプレート仮引数と呼ばれ、関数テンプレートを使用するソースコードを書くと、コンパイラによって、具体的な型に置き換えられたコードが生成されます。

// テンプレート仮引数T に当たる型を明示的に指定して呼び出す
int ans1 = max<int>(10, 20);
double ans2 = max<double>(10.15, 10.25);

// 実引数から型推論させることも可能
int ans3 = max(10, 20);    // 10 と 20 は int型だから、T は int型だと推測
auto ans4 = max(10, 20);   // 戻り値型も T だから int型だと分かる。よって、受け取り側の変数の型も型推論できる

使用時に記述する具体的な型名のほうをテンプレート実引数と呼びます。上記のコードのように明示的に指定できるほか、(関数に渡すほうの)実引数から型推論させることも可能です。

こうしたコードから、テンプレート仮引数 T が int になったものと、double になったものがそれぞれ必要とされていることが分かるので、コンパイラはそれぞれのコードを生成します。

// T に int を当てはめたバージョン
int max(int a, int b)
{
    return a >= b ? a : b;
}

// T に double を当てはめたバージョン
double max(double a, double b)
{
    return a >= b ? a : b;
}

このように、型が抽象化されたテンプレートから、型を具体化したコードを作り出すことを、テンプレートの実体化と呼びます。また、実体化されたコードのことを指して、テンプレートの特殊化(特殊化バージョン)と呼びます。実際に呼び出さるのは特殊化されたコードの方です。テンプレートはその名の通り、実際のコードを生成するための雛形に過ぎません。

特定のテンプレート実引数に対してだけ、異なるコードを使わせたいという場合に、テンプレートの明示的特殊化をおこなうことができます。次のコードは、テンプレート実引数が MyData型の場合にだけ異なるコードを使用します。コードが異なって良いということに注意してください。

// プライマリテンプレート
template <typename T>
T max(T a, T b)
{
    return a >= b ? a : b;
}

// MyData型に明示的特殊化した関数テンプレート
template <>    // テンプレート仮引数はなくなったが、元がテンプレートであることを示すために必要
MyData max(MyData a, MyData b)
{
    // 実装内容が変えられる
    return MyData::max(a, b);
}

明示的特殊化されたバージョンに対して、元になっている側のテンプレートのことを、プライマリテンプレートと呼びます。

クラステンプレートの場合は、テンプレート仮引数の一部だけを明示的に指定したテンプレートの部分特殊化が行えますが、関数テンプレートでは行えません。関数テンプレートをオーバーロードすることが代替手段になります。

C++ の関数テンプレートについては C++編【言語解説】第9章で、明示的特殊化については、第23章で解説しています。


参考リンク

更新履歴


用語集のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
Twitter でツイート Twitter をフォロー LINE で送る
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー