テンプレートプログラミング入門:関数テンプレートとクラステンプレート

関数テンプレート

関数テンプレートは、データ型に依存しない汎用的な関数を定義するための仕組みです。コンパイル時にテンプレートから特定の型に応じた関数が生成され、コードの再利用性と柔軟性を高めます。

基本構文

template <typename T>
T max_value(T a, T b) {
    return (a > b) ? a : b;
}

インスタンス化の方法

  • 暗黙的インスタンス化:引数の型から自動推定
  • 明示的インスタンス化:型を明示的に指定
int main() {
    int x = 5, y = 10;
    double n = 3.5, m = 1.2;

    // 暗黙的インスタンス化
    std::cout << "Max int: " << max_value(x, y) << std::endl;
    std::cout << "Max double: " << max_value(n, m) << std::endl;

    // 明示的インスタンス化
    std::cout << "Max int using explicit: " << max_value<int>(x, y) << std::endl;
    std::cout << "Max double using explicit: " << max_value<double>(n, m) << std::endl;

    return 0;
}

応用例

変数交換関数

template <typename T>
void swap_values(T &x, T &y) {
    T temp = x;
    x = y;
    y = temp;
}

配列の最大値検索

template <class T>
T find_max(T array[], int size) {
    T max_val = array[0];
    for(int i = 1; i < size; ++i) {
        if(max_val < array[i]) {
            max_val = array[i];
        }
    }
    return max_val;
}

複数の型パラメータ

template <typename T1, typename T2>
T2 process_data(T1 arg1, T2 arg2) {
    std::cout << arg1 << " " << arg2 << std::endl;
    return arg2;
}

クラステンプレート

STL(標準テンプレートライブラリ)の基本となる仕組みで、型に依存しないクラスの定義が可能です。

定義方法

template <typename Type>
class MyContainer {
    // クラス定義
};

インスタンス化

MyContainer<int> int_container;
MyContainer<std::string> string_container;

配列テンプレートの例

template <class T, int size>
class StaticArray {
private:
    T data[size];
public:
    T& operator[](int index) {
        if(index < 0 || index >= size) {
            throw std::out_of_range("Index out of range");
        }
        return data[index];
    }
};

テンプレートの特殊化

特定の型に対して特別な実装を提供する仕組みです。

// 一般化されたバージョン
template <typename T>
class Container {
    // 通常の実装
};

// int型に対する特殊化
template <>
class Container<int> {
    // int型専用の実装
};

部分特殊化

template <typename T1, typename T2>
class Pair {
    // 通常の実装
};

// 第二型パラメータがintの場合の部分特殊化
template <typename T1>
class Pair<T1, int> {
    // 特殊化された実装
};

テンプレートの応用

メンバーテンプレート

template <typename T>
class Outer {
private:
    template <typename V>
    class Inner {
        // ...
    };
    Inner<T> value_container;
};

テンプレートのテンプレート引数

template <template <typename, typename> class Container, typename T, typename A = std::allocator<T>>
class Wrapper {
    Container<T, A> container;
};

エイリアステンプレート(C++11)

template <typename T>
using Array12 = std::array<T, 12>;

Array12<double> measurements;

タグ: テンプレート C++ 関数テンプレート クラステンプレート ジェネリックプログラミング

8月1日 03:18 投稿