C++の関数テンプレートとは、型に依存しない汎用的な関数を定義するための仕組みです。
通常の関数では、引数や戻り値の型をあらかじめ決めておく必要があります。
たとえば、整数を扱う関数を作った場合、そのままでは小数や文字列など別の型には対応できません。
一方、関数テンプレートを使うと、具体的な型をあとから決められる関数を作れます。
これにより、整数、小数、文字列、独自クラスなど、さまざまな型に対して同じような処理を再利用できます。
関数テンプレートは、C++の標準ライブラリでも広く使われています。
たとえば、値を比較する関数、並べ替えを行う関数、コンテナを操作する関数など、多くの機能がテンプレートを活用して作られています。
関数テンプレートを使う目的
同じ処理を複数の型で使い回すため
関数テンプレートの主な目的は、同じ処理を複数の型に対して使い回すことです。
たとえば、2つの値を比較して大きい方を返す処理は、整数でも小数でも使いたい場面があります。
通常の関数だけで対応しようとすると、整数用、小数用、長整数用など、型ごとに似たような関数を何度も書く必要があります。
関数テンプレートを使えば、このような重複を減らせます。
処理の内容は1つにまとめ、実際に使う型に応じてコンパイラが適切な関数を生成してくれます。
型安全に汎用処理を書くため
関数テンプレートは、単に「どんな型でも受け取る」ための仕組みではありません。
C++では、テンプレートを使っても型チェックはきちんと行われます。
関数の中で使っている操作が、その型に対して有効でなければコンパイルエラーになります。
たとえば、関数内で足し算をしている場合、その型に対して足し算ができる必要があります。
比較をしている場合は、その型に対して比較演算ができる必要があります。
このように、関数テンプレートは汎用的でありながら、型安全性も保てる仕組みです。
関数テンプレートの基本的な考え方
型を仮の名前で表す
関数テンプレートでは、具体的な型の代わりに、仮の型名を使います。
よく使われる仮の型名には、T、U、V などがあります。
これは「Type」の頭文字として使われることが多く、任意の型を表すものです。
たとえば、T という型パラメータを使うと、実際に関数を呼び出したときに、T が整数型になったり、小数型になったりします。
つまり、関数テンプレートでは、関数を定義する時点では具体的な型を決めず、呼び出し時に使われる値から型を決めるという考え方をします。
コンパイル時に型が決まる
関数テンプレートは、実行時に型を判定する仕組みではありません。
実際には、コンパイル時に使われた型に応じて具体的な関数が作られます。
この仕組みをインスタンス化といいます。
たとえば、整数で関数テンプレートを使えば整数用の関数が、小数で使えば小数用の関数が必要に応じて生成されます。
そのため、関数テンプレートは実行時の余分な型判定を必要とせず、通常の関数に近い性能で動作しやすいという特徴があります。
typename と class の違い
型パラメータでは基本的に同じ意味
関数テンプレートでは、型パラメータを宣言するときに typename を使うことが多いです。
また、同じ場面で class を使うこともできます。
テンプレートの型パラメータを宣言する文脈では、typename と class は基本的に同じ意味です。
つまり、どちらを使っても「ここには任意の型が入る」という意味になります。
現代的には typename が分かりやすい
現在のC++では、型パラメータを表す場合、typename を使う書き方が分かりやすいとされています。
理由は、typename という名前から「これは型名を表している」と読み取りやすいからです。
ただし、古いコードやライブラリでは class が使われていることも多くあります。
どちらも読めるようにしておくとよいでしょう。
別の文脈では意味が変わる場合がある
注意点として、C++全体で見ると typename と class が常に同じ意味になるわけではありません。
テンプレートの型パラメータを宣言する場面では同じように使えますが、依存名が型であることを示す場面などでは typename が特別な意味を持ちます。
そのため、初心者のうちは「関数テンプレートの型パラメータでは、typename と class はほぼ同じ」と理解しておくとよいです。
テンプレート引数の自動推論
引数から型を自動で判断する
関数テンプレートでは、多くの場合、呼び出し時に型を明示する必要はありません。
関数に渡された引数をもとに、コンパイラが型を自動的に判断してくれます。
これをテンプレート引数推論といいます。
たとえば、整数を渡せば型パラメータは整数型として扱われ、小数を渡せば小数型として扱われます。
この仕組みによって、テンプレートを使う側は通常の関数とほぼ同じ感覚で呼び出せます。
型を明示することもできる
テンプレート引数は、自動推論に任せるだけでなく、明示的に指定することもできます。
たとえば、整数と小数を同時に渡すような場面では、コンパイラが型を1つに決められないことがあります。
そのような場合、使用する型を明示することで呼び出せる場合があります。
型を明示すると、コンパイラはその型を前提にして引数を扱います。
そのため、必要に応じて暗黙の型変換が行われることがあります。
同じ型パラメータを複数の引数に使う場合
同じ型として推論できる必要がある
関数テンプレートで1つの型パラメータを複数の引数に使う場合、それらの引数から同じ型として推論できる必要があります。
たとえば、2つの引数がどちらも整数であれば、型パラメータは整数型として推論できます。
2つの引数がどちらも小数であれば、小数型として推論できます。
一方、片方が整数で、もう片方が小数の場合、コンパイラは型パラメータを整数型にすべきか小数型にすべきか判断できないことがあります。
通常の関数とは型変換の扱いが異なる
通常の関数では、引数の型が少し違っていても暗黙の型変換によって呼び出せることがあります。
しかし、関数テンプレートの型推論では、推論の段階で都合よく型をそろえてくれるとは限りません。
そのため、関数テンプレートでは「最終的に変換できそうか」よりも、「引数から型パラメータを矛盾なく推論できるか」が重要になります。
異なる型を扱うなら型パラメータを分ける
整数と小数のように異なる型を同時に扱いたい場合は、型パラメータを複数用意する方法があります。
たとえば、1つ目の引数用の型、2つ目の引数用の型を別々にすると、それぞれ異なる型として扱えます。
このようにすると、異なる型の値を受け取り、その結果に応じた戻り値を返すような関数を作りやすくなります。
戻り値の型に注意する
型を固定すると意図しない変換が起きることがある
関数テンプレートでは、戻り値の型をどのように決めるかが重要です。
特に、複数の型を扱う関数では注意が必要です。
たとえば、整数と小数を足した結果は小数になるのが自然です。
しかし、戻り値の型を整数側に固定してしまうと、小数部分が失われる可能性があります。
このような意図しない型変換は、バグの原因になります。
auto 戻り値を使うと自然な型になりやすい
C++14以降では、関数の戻り値に auto を使うことで、戻り値の型をコンパイラに推論させることができます。
これにより、計算結果に応じた自然な型を戻り値にしやすくなります。
たとえば、整数と小数を計算した結果であれば、小数型として返すような形にできます。
ただし、戻り値の型が分かりにくくなることもあるため、複雑な処理では読みやすさとのバランスも大切です。
関数テンプレートで使える型の条件
すべての型で使えるわけではない
関数テンプレートは便利ですが、どんな型でも必ず使えるわけではありません。
関数内で行っている操作が、その型に対して有効である必要があります。
たとえば、足し算を行う関数テンプレートなら、その型で足し算ができなければなりません。
比較を行う関数テンプレートなら、その型で比較ができなければなりません。
出力を行う関数テンプレートなら、その型を出力する仕組みが必要です。
エラーの原因は関数内の操作に注目する
テンプレートでコンパイルエラーが出た場合、まず見るべきなのは、関数内でどのような操作をしているかです。
たとえば、比較演算をしているなら、その型で比較できるかを確認します。
足し算をしているなら、その型で足し算できるかを確認します。出力しているなら、その型を出力できるかを確認します。
テンプレートのエラーは長くなりがちですが、基本的には「その型に対して、関数内の処理が成立しているか」を見ることが重要です。
関数テンプレートとオーバーロード
通常の関数と同じ名前で定義できる
関数テンプレートは、通常の関数と同じ名前で定義できます。
このとき、呼び出し時には候補となる関数の中から、もっとも適したものが選ばれます。
これをオーバーロード解決といいます。
テンプレート関数と通常の関数が両方候補になることもあります。
必ず通常の関数が優先されるわけではない
よくある説明として、「通常の関数がテンプレート関数より優先される」と言われることがあります。
これは一部のケースでは正しいですが、常にそうとは限りません。
C++では、通常の関数かテンプレート関数かだけで単純に決まるのではなく、引数にどれだけぴったり合うかによって選ばれます。
通常の関数を呼び出すには型変換が必要で、テンプレート関数なら変換なしで呼び出せる場合、テンプレート関数が選ばれることもあります。
そのため、正確には「オーバーロード解決によって最適な候補が選ばれる」と理解するのがよいです。
特定の型だけ処理を変えたい場合に使える
オーバーロードを使うと、基本的にはテンプレートで汎用的に処理し、特定の型だけ通常の関数で別処理にすることができます。
たとえば、多くの型では同じ表示処理を行い、文字列だけ特別な表示にする、といった使い方ができます。
実務では、関数テンプレートの特殊化よりも、オーバーロードの方が分かりやすく扱いやすいことが多いです。
関数テンプレートの特殊化
特定の型だけ実装を変えられる
関数テンプレートでは、特定の型に対してだけ処理を変えることができます。これを特殊化といいます。
たとえば、通常は汎用的な処理を行い、特定の型だけ別の処理にする、といったことが可能です。
実務ではオーバーロードが使われることも多い
関数テンプレートの特殊化は便利ですが、オーバーロード解決との関係がやや複雑になることがあります。
そのため、関数の振る舞いを型ごとに変えたい場合は、まず通常のオーバーロードを検討するのが一般的です。
特殊化は、テンプレートの仕組みを深く理解してから使う方が安全です。
関数テンプレートと参照
値渡しではコピーが発生する
関数テンプレートでも、通常の関数と同じように、引数を値渡しにするとコピーが発生します。
整数や小数のような小さな型であれば、値渡しでも大きな問題にならないことが多いです。
しかし、文字列や大きなオブジェクト、コンテナなどを値渡しすると、コピーのコストが高くなる場合があります。
const 参照を使うとコピーを避けやすい
大きなオブジェクトを読み取るだけであれば、const 参照で受け取る方法がよく使われます。
これにより、コピーを避けつつ、関数内で値を変更しないことも示せます。
表示するだけの関数や、値を調べるだけの関数では、const 参照が適していることが多いです。
小さな型では値渡しも自然
一方で、すべての場面で const 参照が最適というわけではありません。
整数、小数、ポインタ、イテレータのような小さくコピーが安い型では、値渡しの方が単純で扱いやすい場合もあります。
テンプレートでは、対象となる型が幅広くなるため、値渡しにするか参照渡しにするかは、関数の目的に応じて考える必要があります。
完全転送と転送参照
引数の性質を保ったまま別の関数へ渡す
より高度なテンプレートの使い方として、完全転送があります。
完全転送とは、受け取った引数が左辺値なのか右辺値なのかといった性質を保ったまま、別の関数へ渡す仕組みです。
これは、ラッパー関数や汎用的なライブラリを作るときによく使われます。
T&& が転送参照になる場合がある
テンプレートで型パラメータ T に対して T&& のような形を使うと、状況によって左辺値にも右辺値にも対応できます。
このような参照は、標準的には転送参照と呼ばれます。
以前は「ユニバーサル参照」と呼ばれることもありましたが、現代的には「転送参照」という表現の方が適切です。
初心者は後回しでもよい
完全転送や転送参照は、関数テンプレートの中でも高度な内容です。
最初から無理に理解しようとすると混乱しやすいため、まずは通常の型パラメータ、値渡し、const 参照、戻り値の型推論などを理解する方が大切です。
C++20のConceptsによる制約
テンプレートに使える型を制限できる
C++20以降では、Conceptsを使って、テンプレートに渡せる型を制限できます。
たとえば、整数型だけを受け付ける、比較できる型だけを受け付ける、といった制約を表現できます。
従来のテンプレートでは、条件に合わない型を渡したときにエラーメッセージが長く分かりにくくなることがありました。
Conceptsを使うと、テンプレートがどのような型を想定しているのかを明示しやすくなります。
エラーを分かりやすくしやすい
Conceptsを使う大きなメリットは、エラーを分かりやすくしやすいことです。
たとえば、「整数型でなければならない」という制約を付けておけば、小数や文字列を渡したときに、制約を満たしていないことが比較的分かりやすくなります。
また、コードを読む人にとっても、その関数テンプレートがどのような型を想定しているのか理解しやすくなります。
制約の範囲には注意が必要
Conceptsを使う場合でも、制約の意味を正しく理解する必要があります。
たとえば、「整数型」を表す制約には、一般的に想像する数値だけでなく、場合によっては真偽値や文字型が含まれることもあります。
そのため、実際の用途に合った制約になっているかを確認することが大切です。
C++20の auto 引数
簡潔に関数テンプレートを書ける
C++20以降では、関数の引数に auto を使うことで、簡潔に関数テンプレートのような処理を書けます。
これは、略記関数テンプレートと呼ばれる機能です。
簡単な汎用関数であれば、通常のテンプレート構文よりも短く書けるため便利です。
複雑な処理では通常のテンプレート構文が分かりやすい
ただし、すべての場合で auto 引数を使えばよいわけではありません。
型パラメータに名前を付けて使い回したい場合や、複数の引数を同じ型として扱いたい場合、制約を細かく付けたい場合などは、通常のテンプレート構文の方が分かりやすいことがあります。
簡単な処理では auto 引数、明確な型設計が必要な処理では通常のテンプレート構文、というように使い分けるとよいです。
関数テンプレートと配列
配列を引数にするとポインタとして扱われやすい
関数テンプレートで配列を扱う場合には注意が必要です。
関数の引数として配列を受け取る形にしても、多くの場合、配列そのものではなく先頭要素へのポインタとして扱われます。
そのため、関数内で配列の要素数を自動的に知ることはできません。
配列サイズを別に渡す必要がある
配列の要素を処理する関数では、配列のサイズを別に渡すことがよくあります。
これは、関数側が配列の長さを知らないためです。
ただし、C++では配列サイズもテンプレート引数として受け取る高度な方法があります。
これを使うと、配列の要素数をコンパイル時に扱うこともできます。
初心者の段階では、まず「配列を関数に渡すとサイズ情報が失われやすい」という点を理解しておくとよいです。
関数テンプレートと標準ライブラリ
標準ライブラリでも多用されている
C++の標準ライブラリには、関数テンプレートが数多く使われています。
代表的なものに、値を比較する関数、範囲を並べ替える関数、要素を検索する関数などがあります。
これらは、特定の型だけでなく、さまざまな型やコンテナに対して使えるように設計されています。
std::max は同じ型同士が基本
標準ライブラリの比較関数を使うときも、関数テンプレートの型推論に注意が必要です。
たとえば、最大値を求める関数では、基本的に同じ型同士を比較する必要があります。
整数と小数をそのまま渡すと、型パラメータを1つに決められず、エラーになることがあります。
その場合は、あらかじめ型をそろえるか、テンプレート引数を明示する必要があります。
std::sort もテンプレートを活用している
並べ替えを行う標準ライブラリの関数も、テンプレートを活用しています。
このような関数は、配列やコンテナそのものではなく、反復子を通じて要素を操作します。
そのため、整数の配列、小数の配列、文字列の配列、独自型のコンテナなど、さまざまな対象を同じ関数で扱えるようになっています。
関数テンプレートとマクロの違い
マクロは文字列置換である
C++では、関数テンプレートと似た目的でマクロが使われることもあります。
しかし、マクロはコンパイル前の単純な文字列置換です。
そのため、型チェックが行われず、思わぬ副作用が起きることがあります。
特に、マクロの引数に副作用のある式を渡すと、その式が複数回評価される危険があります。
関数テンプレートは型チェックされる
関数テンプレートは通常の関数と同じように扱われるため、型チェックが行われます。
また、マクロのように引数式が展開先で何度も評価される問題を避けやすいです。
そのため、C++で型に依存しない関数を作りたい場合、基本的にはマクロよりも関数テンプレートを使う方が安全です。
関数テンプレートのメリット
コードの重複を減らせる
関数テンプレートを使う最大のメリットは、型ごとに同じような関数を書かなくて済むことです。
同じ処理を整数用、小数用、文字列用と何度も書く必要がなくなり、コードを短く整理できます。
処理内容を変更するときも、テンプレート化された1か所を修正すればよいため、保守性も高くなります。
型安全性を保てる
関数テンプレートは汎用的ですが、型安全性を失うわけではありません。
不適切な型を渡した場合や、その型に対して使えない操作を行った場合は、コンパイル時にエラーになります。
実行時に問題が発覚するのではなく、コンパイル時に検出しやすい点は大きなメリットです。
実行時のオーバーヘッドが少ない
関数テンプレートは、使われた型に応じてコンパイル時にインスタンス化されます。
そのため、実行時に型を調べて処理を分岐する必要がありません。
適切に使えば、通常の関数に近い性能で汎用的な処理を書けます。
関数テンプレートのデメリット
エラーメッセージが長くなりやすい
テンプレートを使ったコードでは、エラーメッセージが長く複雑になることがあります。
特に、標準ライブラリや複数のテンプレートを組み合わせた場合、エラーの原因がすぐに分からないことがあります。
そのような場合は、エラーメッセージ全体に圧倒されるのではなく、最初にエラーが発生した型や、関数内で使っている操作に注目すると原因を見つけやすくなります。
コンパイル時間が長くなることがある
関数テンプレートは、使われた型ごとにインスタンス化されます。
そのため、テンプレートを大量に使ったり、複雑なテンプレートを多用したりすると、コンパイル時間が長くなることがあります。
大規模なC++プロジェクトでは、テンプレートの使い方がビルド時間に影響することもあります。
コードサイズが増えることがある
テンプレートは型ごとに具体的な関数として生成されるため、使い方によっては実行ファイルのサイズが増えることがあります。
これをコード膨張と呼ぶことがあります。
ただし、現代のコンパイラは最適化が進んでいるため、単純なテンプレートであれば過度に心配する必要はありません。
型ごとの挙動に差が出る
同じ関数テンプレートでも、型によって挙動が変わることがあります。
たとえば、割り算を行う関数では、整数同士なら整数除算になり、小数同士なら小数を含む計算になります。
同じテンプレートを使っていても、型によって結果が変わることがあるため、扱う型の性質を理解しておくことが大切です。
関数テンプレートを書くときの注意点
不必要にテンプレート化しない
関数テンプレートは便利ですが、すべての関数をテンプレートにすればよいわけではありません。
特定の型だけを扱うことが明確な処理であれば、通常の関数で十分です。
テンプレート化すると柔軟性は上がりますが、その分、読み手にとって理解しにくくなることもあります。
複数の型で同じ処理を再利用したい場合に、関数テンプレートを使うのが基本です。
型パラメータ名を分かりやすくする
単純な関数テンプレートでは、T や U のような名前がよく使われます。
ただし、型に明確な意味がある場合は、より具体的な名前を付けた方が読みやすくなります。
たとえば、反復子を表す型なら Iterator、値の型を表すなら Value のように、役割が分かる名前を使うとよいです。
戻り値の型を慎重に決める
複数の型を扱う関数テンプレートでは、戻り値の型を固定すると意図しない型変換が起きることがあります。
特に、整数と小数を混ぜて扱う場合や、独自クラスを扱う場合は注意が必要です。
戻り値の型を自動推論させる方法もありますが、読みやすさや意図の明確さとのバランスを考えることが大切です。
ヘッダーに定義を書くことが多い
関数テンプレートは、コンパイラが必要な型に応じてインスタンス化します。
そのため、テンプレートを使う側から定義が見えている必要があります。
通常の関数のように宣言だけをヘッダーに書き、定義をソースファイルに分けると、リンクエラーになることがあります。
そのため、関数テンプレートは基本的にヘッダーファイルに定義まで書くことが多いです。
ただし、明示的インスタンス化を使えば、特定の型についてだけソースファイル側で定義を持たせることもできます。これはやや高度な使い方です。
よくあるミス
異なる型を1つの型パラメータに渡そうとする
初心者がよくつまずくのが、1つの型パラメータに異なる型の引数を渡してしまうケースです。
たとえば、1つの T を2つの引数に使っている関数では、両方の引数から同じ型を推論できる必要があります。
整数と小数を同時に渡すと、T を整数にすべきか小数にすべきか判断できず、エラーになることがあります。
この場合は、型を明示するか、複数の型パラメータを使う設計にする必要があります。
必要な演算子が定義されていない型を渡す
関数テンプレートの中で足し算をしているなら、渡す型でも足し算ができる必要があります。
比較をしているなら、比較演算ができる必要があります。
独自クラスをテンプレート関数に渡す場合、その関数内で使われる演算子や操作が定義されているかを確認する必要があります。
文字列リテラルの扱いを誤解する
文字列を扱うときも注意が必要です。
C++の文字列リテラルは、必ずしも文字列クラスとして扱われるわけではありません。
文字列リテラル同士を足し算しても、文字列結合になるとは限りません。
文字列結合をしたい場合は、文字列クラスとして扱う必要があります。
この点は、関数テンプレートで文字列を扱うときに誤解しやすいポイントです。
テンプレートをソースファイルだけに定義する
関数テンプレートを通常の関数と同じ感覚で、宣言をヘッダーに、定義をソースファイルに分けると、リンクエラーになることがあります。
テンプレートは、使われた型に応じてコンパイル時に具体化されるため、使用する側から定義が見えている必要があります。
初心者のうちは、関数テンプレートはヘッダーに定義まで書くと覚えておくとよいです。
関数テンプレートの学習順序
まず通常の関数を理解する
関数テンプレートを理解するには、まず通常の関数をしっかり理解しておく必要があります。
引数、戻り値、値渡し、参照渡し、オーバーロードなどの基本が分かっていると、テンプレートも理解しやすくなります。
次に型パラメータを理解する
通常の関数との違いは、型を固定せず、型パラメータとして扱う点です。
まずは、1つの型パラメータを使う単純な関数テンプレートから理解するとよいです。
複数の型パラメータに進む
1つの型パラメータに慣れたら、複数の型パラメータを使う関数テンプレートを学びます。
異なる型の引数を受け取る場面では、複数の型パラメータが必要になります。
参照や戻り値の型を理解する
次に、値渡し、const 参照、戻り値の型推論などを理解します。
このあたりを理解すると、より実用的な関数テンプレートを書けるようになります。
Conceptsや完全転送は後から学ぶ
Concepts、完全転送、転送参照などは便利ですが、やや高度です。
最初からすべて理解しようとせず、基本的な関数テンプレートを読める・書けるようになってから学ぶとよいです。
関数テンプレートを使うべき場面
複数の型で同じ処理を使いたい場合
関数テンプレートが向いているのは、複数の型に対して同じ処理を行いたい場合です。
たとえば、値を比較する、値を表示する、範囲を処理する、同じ計算を行うといった場面です。
型に依存しない処理を書きたい場合
処理の本質が型に依存しない場合も、関数テンプレートが向いています。
たとえば、値を入れ替える処理や、同じ形式で出力する処理などは、型が違っても考え方は共通です。
標準ライブラリのような汎用処理を作りたい場合
標準ライブラリのように、さまざまな型やコンテナで使える汎用的な処理を作りたい場合、関数テンプレートは非常に有効です。
ただし、汎用性を高めるほど設計は難しくなるため、必要以上に複雑にしないことも大切です。
関数テンプレートを使わない方がよい場面
特定の型だけを扱う場合
処理対象が明確に1つの型だけであれば、通常の関数で十分です。
たとえば、整数専用の処理や、特定のクラス専用の処理であれば、無理にテンプレート化する必要はありません。
型ごとに処理内容が大きく異なる場合
型ごとに処理内容が大きく変わる場合も、関数テンプレートが必ずしも適しているとは限りません。
その場合は、オーバーロードやクラス設計を見直した方が分かりやすくなることがあります。
読みやすさが下がる場合
テンプレートを使うと、コードが抽象的になります。
汎用性は高まりますが、読み手にとって処理の意図が分かりにくくなることもあります。
そのため、テンプレートは「必要だから使う」ものであり、「使えるから使う」ものではありません。
まとめ
C++の関数テンプレートは、型に依存しない汎用的な関数を作るための機能です。
具体的な型をあらかじめ決めずに関数を定義し、実際に呼び出されたときの引数から型を推論します。
使われた型に応じて、コンパイル時に具体的な関数が生成されます。
関数テンプレートを使うと、同じ処理を型ごとに何度も書く必要がなくなり、コードの重複を減らせます。
また、型チェックも行われるため、汎用的でありながら型安全なコードを書けます。
一方で、関数テンプレートはどんな型でも使えるわけではありません。
関数内で使っている演算子や操作が、その型に対して有効である必要があります。
また、テンプレートのエラーメッセージは長くなりやすく、コンパイル時間やコードサイズに影響することもあります。
初心者がまず押さえるべきポイントは、次の通りです。
- 関数テンプレートは、複数の型で同じ処理を使い回すための仕組み
- 型パラメータを使って、具体的な型をあとから決める
- 型はコンパイル時に決まる
- 1つの型パラメータを複数の引数に使う場合、同じ型として推論できる必要がある
- 関数内で使っている操作が、その型で有効でなければならない
- 複数の型を扱う場合は、型パラメータを分けたり、戻り値の型に注意したりする
- 関数テンプレートは基本的にヘッダーに定義を書くことが多い
関数テンプレートを理解すると、C++でより再利用性が高く、柔軟なコードを書けるようになります。
標準ライブラリの仕組みを理解するうえでも重要な機能なので、基本から順番に身につけていくとよいでしょう。
以上、C++の関数テンプレートについてでした。
最後までお読みいただき、ありがとうございました。
