これは、VS2012 に同梱されている C++ 標準ライブラリの xutility ヘッダーからのものです。
template<class _Elem1,
class _Elem2>
struct _Ptr_cat_helper
{ // determines pointer category, nonscalar by default
typedef _Nonscalar_ptr_iterator_tag type;
};
template<class _Elem>
struct _Ptr_cat_helper<_Elem, _Elem>
{ // determines pointer category, common type
typedef typename _If<is_scalar<_Elem>::value,
_Scalar_ptr_iterator_tag,
_Nonscalar_ptr_iterator_tag>::type type;
};
具体的には、2 番目の _Ptr_cat_helper 宣言の性質は何ですか? 宣言子 _Ptr_cat_helper の後の山括弧は、特殊化のように見せます。ただし、テンプレートを特殊化するために完全または部分的な型を指定する代わりに、テンプレート引数を複数回繰り返すだけです。
私は前にそれを見たことはないと思います。それは何ですか?
アップデート
両方のテンプレート引数が同じ型であるテンプレートのインスタンス化に特殊化が適用されることは明らかですが、これが完全な特殊化を構成するのか部分的な特殊化を構成するのか、またはその理由については明確ではありません。
すべてのテンプレート引数が明示的に提供されるか、デフォルトの引数によって提供され、テンプレートをインスタンス化するために提供されたとおりに使用される場合、特殊化は完全な特殊化であり、逆に、すべてのテンプレートパラメーターではないにしても、特殊化は部分的であると考えましたそれらの 1 つまたは複数 (すべてではない) を提供する特殊化のために、および/またはテンプレート引数が特殊化パターンによって変更された形式で使用された場合に必要でした。例えば
特殊化がテンプレート引数のすべてではなく少なくとも 1 つを提供しているため、部分的な特殊化。
template<typename T, typename U>
class G { public: T Foo(T a, U b){ return a + b; }};
template<typename T>
class G<T, bool> { public: T Foo(T a, bool b){ return b ? ++a : a; }};
特殊化により、指定されたテンプレート引数が部分的にしか使用されないため、部分的な特殊化。
template<typename T>
class F { public: T Foo(T a){ return ++a; }};
template<typename T>
class F<T*> { public: T Foo(T* a){ return ++*a; }};
この 2 番目の例では、テンプレートが A<char*> を使用してインスタンス化された場合、テンプレート内の T は実際には char 型になります。つまり、指定されたテンプレート引数は、特殊化パターンの適用により部分的にしか使用されません。
それが正しい場合、元の質問のテンプレートは部分的な専門化ではなく完全な専門化にはなりません。そうでない場合、私の誤解はどこにありますか?