クラス テンプレートと関数テンプレートの違いと、それぞれをどこで使用すればよいかを知りたいです。
2 に答える
インスタンス化されると、クラス テンプレートはクラスになり、関数テンプレートは関数になります。例:
//Defines a template for a class that can hold two
//objects.
template<typename T1, typename T2>
struct pair {
T1 first;
T2 second;
};
//Defines a template for a function that gives the
//minimum of two values.
template<typename T>
T min(T a, T b) {
return a < b ? a : b;
}
通常のコードでは、型によってパラメーター化されたクラスを作成する場合はクラス テンプレートを使用し、さまざまな型を操作できる関数を作成する場合は関数テンプレートを使用します。
関数テンプレートは、ファクトリ関数の作成に役立つ型推定も実行できます。
//Deduces the types of T1 and T2, so
//for example, a pair<int, double> can be created
//by `make_pair(10, 1.2)`
template<typename T1, typename T2>
pair<T1, T2> make_pair(T1&& t1, T2&& t2) {
return {std::forward<T1>(t1), std::forward<T2>(t2)};
}
クラス テンプレートを使用して、コンパイル時に実行されるプログラムを作成できます (型を値として使用し、パターン マッチングを使用したテンプレートのインスタンス化を純粋な関数として使用します)。これの簡単な例はconst
、タイプからすべてを削除するクラス テンプレートのセットです。
//Removes all `const` from a type, for example:
//`remove_const_recursive<int const*const volatile>::type`
//is the type `int*volatile`.
template<typename T> struct remove_const_recursive { typedef T type; };
template<typename T> struct remove_const_recursive<T const volatile> {
typedef typename remove_const_recursive<T>::type volatile type;
};
template<typename T> struct remove_const_recursive<T volatile> {
typedef typename remove_const_recursive<T>::type volatile type;
};
template<typename T> struct remove_const_recursive<T const> {
typedef typename remove_const_recursive<T>::type type;
};
template<typename T> struct remove_const_recursive<T&> {
typedef typename remove_const_recursive<T>::type& type;
};
template<typename T> struct remove_const_recursive<T*> {
typedef typename remove_const_recursive<T>::type* type;
};
テンプレートを使えば使うほど、さまざまな使い方ができることに気づくでしょう。式テンプレートを使用すると、特定の種類のコードを高速化したり、ドメイン固有の言語を作成したりできます。テンプレートのメタプログラミングとタプルを使用して、さまざまな面倒なコードを自動的に作成できます。また、テンプレートの構文が鈍く、パフォーマンスと意味力が限られているということは、テンプレートが提供する利点が必ずしもコストを上回るとは限らないことを意味することにも気付くかもしれません。
関数テンプレートは、引数の型から特殊化の型を推測しようとします。
クラスは可能ですが、関数テンプレートは部分的に特化することはできません。
関数テンプレートは既定のテンプレート パラメーターを持つことができませんが、クラスはできます。