テンプレート: 型の抽象化

同じロジックを任意の型で再利用。STLの基盤技術。

テンプレート
型をパラメータ化してコードを再利用。
インスタンス化
具体的な型でコードを生成。
typename
型パラメータを宣言するキーワード。

テンプレートとは?

型抜き

同じ型抜きで、チョコ生地もバニラ生地もクッキーにできる。

なぜテンプレートが必要か?

C++では、同じロジックを異なる型で再利用したい場面がよくあります。例えば、max()関数はint、double、std::stringなど様々な型で動作させたい場合があります。テンプレートを使うことで、型ごとに関数を書く必要がなくなり、コードの重複を排除できます。これはDRY(Don't Repeat Yourself)原則の実現であり、メンテナンス性を大幅に向上させます。

また、テンプレートはコンパイル時に型ごとに最適化されたコードを生成するため、マクロや関数ポインタよりも型安全性が高く、実行時のパフォーマンスも優れています。

いつ使うか?

  • 同じロジックを複数の型で再利用する場合(コンテナ、アルゴリズムなど)
  • 型安全性を保ちたい場合(コンパイル時の型チェック)
  • STLのコンテナやアルゴリズムを理解する場合(STL自体がテンプレートで実装されている)

実践テクニック

SFINAE(Substitution Failure Is Not An Error): テンプレートのオーバーロード解決時に、コンパイルエラーを無視する仕組み。これを活用して、特定の型に対してのみ有効な関数を定義できます。
コンセプト(Concepts): テンプレートパラメータに型制約(typename T: class MyClass)を付けることで、特定の条件を満たす型のみを受け入れるようにできます。
型推論(Type Deduction): 関数テンプレートの引数から型を自動的に推論できます。例えば、max(3, 5)と書くと、Tはintとして推論されます。
Function Template
template<typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}
int main() {
int i = max(3, 5); // T = int
double d = max(3.14, 2.71); // T = double
std::string s = max("apple", "banana"); // T = const char*
}
実行結果
i = 5
d = 3.14
s = "banana"
Bad
// ❌ Bad: 型ごとに関数を書く
int maxInt(int a, int b) { return (a > b) ? a : b; }
double maxDouble(double a, double b) { return (a > b) ? a : b; }
std::string maxString(std::string a, std::string b) { ... }
Good
// ✅ Good: テンプレート1つでOK
template<typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}

クラステンプレート

Class Template with Non-Type Parameter
template<typename T, size_t N>
class Array {
T data_[N];
public:
T& operator[](size_t i) { return data_[i]; }
constexpr size_t size() const { return N; }
};
Array<int, 10> arr; // 10個のint
arr[0] = 42;

合格ライン

関数テンプレートを書ける
typename と class の違いを知っている

参考リンク

演習課題

課題1: 関数テンプレート
任意の型の2つの値を交換する swap テンプレート関数を作成してください。
課題2: クラステンプレート
固定サイズの配列をラップする Array クラステンプレートを作成してください。

次のステップ