部分的なテンプレートの特殊化は、C++ でのジェネリック プログラミングの最も重要な概念の 1 つです。例: 一般的な swap 関数を実装するには:
template <typename T>
void swap(T &x, T &y) {
const T tmp = x;
y = x;
x = tmp;
}
O(1) スワップをサポートするベクトルに特化するには:
template <typename T, class Alloc>
void swap(vector<T, Alloc> &x, vector<T, Alloc> &y) { x.swap(y); }
そのため、汎用関数で swap(x, y) を呼び出すと、常に最適なパフォーマンスを得ることができます。
代替言語で同等のもの(または言語がスワップの概念をサポートしていない場合は、言語の部分的な特殊化の標準的な例)を投稿できれば、非常に感謝しています。
編集:したがって、回答/コメントした多くの人々は、部分的な特殊化が何であるかを本当に知らず、一般的なスワップの例が一部の人々の理解を妨げているようです。より一般的な例は次のとおりです。
template <typename T>
void foo(T x) { generic_foo(x); }
部分的な特殊化は次のようになります。
template <typename T>
void foo(vector<T> x) { partially_specialized_algo_for_vector(x); }
完全な専門化は次のようになります。
void foo(vector<bool> bitmap) { special_algo_for_bitmap(bitmap); }
なぜこれが重要なのですか?ジェネリック関数で foo(anything) を呼び出すことができるため:
template <typename T>
void bar(T x) {
// stuff...
foo(x);
// more stuff...
}
コンパイル時に最も適切な実装を取得します。これは、C++ が最小限のパフォーマンス ペナルティで抽象化を実現する 1 つの方法です。
「部分専門化」の概念を明確にするのに役立つことを願っています。ある意味で、これは C++ が明示的なパターン マッチング構文 (Ocaml/F# の match キーワードなど) を必要とせずに型パターン マッチングを行う方法であり、ジェネリック プログラミングの邪魔になることがあります。