始めに、テンプレートがどういった機能なのかは、
テンプレートとは?で説明しています。
テンプレート関数とは?
下記のコードは、テンプレートとは?で、例として使ったプログラムです。
#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';
}
このプログラムは見て頂ければ理解できると思いますので、
説明は省略します。
赤文字の部分がチェックポイントです。