0Pricing
C++ Academy · レッスン

関数テンプレートとクラステンプレート再入門

適切なテンプレート構文でジェネリック関数とクラスを記述します。

「関数テンプレートとクラステンプレート再入門」はCoddyKit上の無料C++ Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC++ Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C++ Academyコースには全4レッスンが含まれています。

テンプレートを使う理由

テンプレートを使うと、コードを一度だけ記述し、使用される各型に対応した具体的なバージョンをコンパイラーに生成させることができます。これはジェネリックプログラミングの基本です。

関数テンプレートの構文

template <typename T>で型パラメーターを宣言します。関数シグネチャではTを使用します。

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

std::cout << max_of(3, 7);          // int
std::cout << max_of(2.5, 1.5);      // double

typenameとclass

テンプレートパラメーターの宣言では、キーワードtypenameとclassは置き換えて使用できます。現代的なスタイルではtypenameのほうが一般的です。

複数の型パラメーター

テンプレートには複数の型パラメーターを指定できます。

template <typename T, typename U>
auto combine(T a, U b) -> decltype(a + b) {
    return a + b;
}

非型パラメーター

テンプレートパラメーターには、整数、列挙型、ポインターなど、型ではない値も指定できます。

template <typename T, size_t N>
struct StaticArray {
    T data[N];
};

StaticArray<int, 10> arr;

クラステンプレート

ジェネリッククラスでも同じテンプレート構文を使用します。メンバーやメソッドでは型パラメーターを使用します。

template <typename T>
class Stack {
    std::vector<T> data_;
public:
    void push(T x) { data_.push_back(std::move(x)); }
    T pop()        { T t = std::move(data_.back()); data_.pop_back(); return t; }
};

Stack<int> s1;
Stack<std::string> s2;

クラス外でのメンバー関数

クラス外で定義する場合は、すべてのメンバーにテンプレートのプレフィックスが必要です。

template <typename T>
class Stack {
public:
    void push(T x);
};

template <typename T>
void Stack<T>::push(T x) {
    data_.push_back(std::move(x));
}

デフォルトテンプレート引数

デフォルトの関数引数と同じようなものです。呼び出し側が指定しない場合に使用されます。

template <typename T = int>
class Box {
    T value;
};

Box<> b;       // T is int

テンプレート引数の推論

コンパイラーは、多くの場合、呼び出しからテンプレート引数を推論します。

template <typename T>
void print(T x) { std::cout << x; }

print(42);          // T deduced as int
print("hello");    // T deduced as const char*
print<double>(3);   // explicit

クラステンプレート引数推論(C++17)

C++17では、コンストラクターからクラステンプレート引数を推論できる場合、引数を省略できます。

std::pair p(1, 2.5);            // pair<int, double>
std::vector v{1, 2, 3};         // vector<int>

二段階名前探索

テンプレートでは、名前探索が2段階で行われます。定義時には非依存名、インスタンス化時には依存名が対象です。これにより、多くのエラーを定義時に検出できます。

エラーメッセージ

テンプレートのエラーは難解に見えることがあります。下から上へ読み、ソースの位置に注目し、C++20のコンセプトを使って診断を改善します。

クイックチェック

std::vector<int>を指定しなくてもstd::vector v{1, 2, 3};をコンパイルできる機能は何ですか。

まとめ

テンプレートはコンパイル時に型固有のコードを生成します。template <typename T>で関数テンプレートやクラステンプレートを定義します。可能な場合はコンパイラーが引数を推論しますが、必要に応じて明示的に指定します。

よくある質問

「関数テンプレートとクラステンプレート再入門」レッスンは無料ですか?

はい。「関数テンプレートとクラステンプレート再入門」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C++ Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C++ Academyコースには全4レッスンが含まれています。

「関数テンプレートとクラステンプレート再入門」で何を学びますか?

適切なテンプレート構文でジェネリック関数とクラスを記述します。 ブラウザで直接実行するハンズオンコードでC++ Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C++ Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC++ Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「関数テンプレートとクラステンプレート再入門」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC++ Academyレッスンでコードを書いて実行できますか?

はい。すべてのC++ Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 関数テンプレートとクラステンプレート再入門
  2. テンプレート特殊化:部分特殊化と完全特殊化
  3. 可変長テンプレートとパラメーターパック
  4. constexpr関数とif constexpr
← C++ Academyに戻る