C++ template テンプレート関数とは?

始めに、テンプレートがどういった機能なのかは、
テンプレートとは?で説明しています。


テンプレート関数とは?

下記のコードは、テンプレートとはで、例として使ったプログラムです。

#include <iostream>

using namespace std;

template <typename T> void show(T data);

void main() {
      show(100);
      show(10.5);
}

template <typename T> void show(T data)
{
      cout << data << '\n';
}

まず、テンプレート機能を使った関数をテンプレート関数と言います。

この場合、show関数が当てはまります。

テンプレート関数には、データ型を指定するために
typenameと言うキーワードと共に型識別子が使われます。

(typenameキーワードの代わりにclassキーワードを使ってもOKです。)

template <class T> void show(T data)
{
      cout << data << '\n';
}

型識別子の部分には、データ型が入る事になります。

例えば、int型を指定すると、型識別子である”T”のところがintとなります。

しかし、実際にデータ型を指定してくれるのはコンパイラであり、
プログラマはそれほど意識する必要はありません。

テンプレート関数は、複数のデータ型に対応している事から、
汎用関数と呼ばれることがあります。


テンプレート関数の裏側

テンプレート関数はコンパイル時に、
裏でいろいろな作業を行っています。

コンパイラが、コンパイル時に
テンプレート関数を呼び出すコードを見つけ出し、
その呼ばれるテンプレート関数の引数に対応するデータ型を判別し、
そのデータ型に対応する関数コードを
コンパイラが自動的に生成してくれます


つまり、show(100);と言うコードをコンパイラが発見したら、
実引数から、int型のshow関数が必要である事を導き出し、
引数がint型のshow関数を作ってくれると言う事になります。

もう1つのshow(10.5);と言うコードも同じです。

実引数から、double型のshow関数が必要である事を導き出し、
引数がdouble型のshow関数を作ってくれます。

このプログラム例の場合、
以下のような関数が見えないところで作成されています。

void show(int data)
{
      cout << data << '\n';
}

void show(double data)
{
      cout << data << '\n';
}

スポンサーリンク

テンプレート関数の多重定義

テンプレート関数は、どのデータ型にも対応する関数ですが、
特定のデータ型の時だけ、違う処理をさせたい場合があります。

こんな場合には、テンプレート関数を多重定義します。

#include <iostream>

using namespace std;

template <typename T> void show(T data);

void main() {
      show(100);
      show(10.5);
      show("C++言語");
}

template <typename T> void show(T data)
{
      cout << data << '\n';
}

template<> void show<char*>(char* data)
{
      cout << "文字列=" << data << '\n';
}

このプログラムでは、テンプレート関数のshowが多重定義されています。

show関数にchar*型の引数が渡された時だけは
2つ目に記述したshow関数が呼ばれるようになります。

やや、面倒な記述が必要なので、
いくつか簡略化した書き方もあります。

1.template<> void show<char*>(char* data)

2.template<> void show<>(char* data)

3.template<> void show(char* data)

4.void show(char* data)

1番目は、そのまま省略せずに記述した例です。

2番目は関数の右側の”<char*>”を省略した例です。

3番目はその”<>”も省略した例です。

そして4番目は、左側のテンプレート記述も省略してしまった例です。

どの記述方法も可能ですが、
4番目の記述は、
「この関数がテンプレート関数の多重定義」である事が
分かりづらいので、オススメできません。

なので、なるべくテンプレートが記述されているパターンを使って下さい。

しかし、4番目に多重定義されたshow関数には、
テンプレート記述がない普通の関数のように見えますが、
これで正しいのです。

このワケは、1つ上の項目”テンプレート関数の裏側”を見てもらうと
理解できるかと思います。


関数テンプレートの多重定義

1つ上の説明では、”テンプレート関数”の多重定義でしたが、
ここでは、”関数テンプレート”の多重定義を説明します。

#include <iostream>

using namespace std;

template <typename T> void show(T data);
template <typename T1, typename T2> void show(T1 data1, T2 data2);

void main() {
      show(100);
      show(10.5);
      show("C++言語");

      show(100, 100);
      show(100, 10.5);
      show(100, "C++言語");
}

template <typename T> void show(T data)
{
      cout << data << '\n';
}

template <typename T1, typename T2> void show(T1 data1, T2 data2)
{
      cout << data1 << '\n';
      cout << data2 << '\n';
}

このプログラムは見て頂ければ理解できると思いますので、
説明は省略します。

赤文字の部分がチェックポイントです。