[C++]template関数の使い方

C++には1つの関数で引数または戻り値の型として複数の型を扱えるようになるtemplateという仕組みがあります。

この記事ではtemplate関数について解説を行います。

template関数のない世界

template関数の有用性を説明するために、template関数のない世界でプログラムを書いてみます。

C++
// 2つの整数値を足す関数
int Add(int a, int b)
{
    return a + b;
}
// 2つの文字列を結合する関数
string Add(string a, string b)
{
    return a + b;
}

題材が悪いので少しわかりづらいですが、2つの関数は同じ関数名関数内の処理も全く同じだけど引数と戻り値の型だけが違っているだけです。

※ 良い題材が思い浮かばなかったので良くない例みたいな関数を書きましたが真似しないでください。

template関数の使い方

前述した例をtemplate関数を使って書いてみると以下のようになります。

C++
// 2つの引数の加算
template<class T> T Add(T a, T b)
{
    return a + b;
}

2つあった関数が1つにまとめられてすっきりとしました。

template関数は、関数の先頭に「template<class T>」を付加することでTというなんでも良いよ型が使えるようになります。

上記の例では、2つの引数と戻り値を全てT型にしていますが、戻り値はint型固定といった使い方も可能です。

template関数を呼び出す際には、普通の関数と同じように呼び出せば良いです。

C++
// int型の加算
int i = Add(1, 2);
// double型の加算
double d = Add(1.5, 2.5);
// string型の加算
string s1 = Add(string("A"), string("B"));
// string型の加算
string s2 = Add<string>("C", "D");

しれっと書きましたが、s2のように関数名の後ろに<型名>と記載することで明示的に型を指定できるようになるため、const char*型の文字列を渡しても自動的にstring型に変換されるようになります。(s1の書き方で引数にstringをつけないとコンパイルエラー)

宣言と定義が別の場合は注意

便利なtemplate関数ですが、宣言(.h)と定義(.cpp)が別の場合に別ファイルから該当関数を使おうとした際にリンクエラーとなります。

リンクエラーとならないためには以下のような記述が必要になります。

C++
// template関数の実体定義
template int Add(int, int);
template double Add(double, double);
template string Add(string, string);

ただし、この記述は面倒臭いので全てヘッダファイルに記述してしまう方もおられるみたいで、その辺は自身の裁量で好きなようにしてもらえば良いかと思います。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です