template<class T1, class T2, int I> class A { };
template<class T, int I> class A<T, T*, I> { };
template<class T1, class T2, int I> class A<T1*, T2, I> { };
template<class T> class A<int, T*, 5> { };
template<class T1, class T2, int I> class A<T1, T2*, I> { };
template<class T> struct A {
struct C {
template<class T2> struct B { };
template<class T2> struct B<T2**> { }; // partial specialization #1
};
};
// partial specialization of A<T>::C::B<T2>
template<class T> template<class T2>
struct A<T>::C::B<T2*> { }; // #2
A<short>::C::B<int*> absip; // uses partial specialization #2
— end example
namespace N {
template<class T1, class T2> class A { }; // primary template
}
using N::A; // refers to the primary template
namespace N {
template<class T> class A<T, T*> { }; // partial specialization
}
A<int,int*> a; // uses the partial specialization, which is found through the using-declaration
// which refers to the primary template
— end example
template <class T, T t> struct C {};
template <class T> struct C<T, 1>; // error
template< int X, int (*array_ptr)[X] > class A {};
int array[5];
template< int X > class A<X,&array> { }; // error
— end example
template<class T1, class T2, int I> class A { }; // #1
template<class T, int I> class A<T, T*, I> { }; // #2
template<class T1, class T2, int I> class A<T1*, T2, I> { }; // #3
template<class T> class A<int, T*, 5> { }; // #4
template<class T1, class T2, int I> class A<T1, T2*, I> { }; // #5
A<int, int, 1> a1; // uses #1
A<int, int*, 1> a2; // uses #2, T is int, I is 1
A<int, char*, 5> a3; // uses #4, T is char
A<int, char*, 1> a4; // uses #5, T1 is int, T2 is char, I is 1
A<int*, int*, 2> a5; // ambiguous: matches #3 and #5
— end example
template <int I, int J> struct A {};
template <int I> struct A<I+5, I*2> {}; // error
template <int I> struct A<I, I> {}; // OK
template <int I, int J, int K> struct B {};
template <int I> struct B<I, I*2, 2> {}; // OK
— end example
template<int I, int J, class T> class X { };
template<int I, int J> class X<I, J, int> { }; // #1
template<int I> class X<I, I, int> { }; // #2
template<int I0, int J0> void f(X<I0, J0, int>); // A
template<int I0> void f(X<I0, I0, int>); // B
template <auto v> class Y { };
template <auto* p> class Y<p> { }; // #3
template <auto** pp> class Y<pp> { }; // #4
template <auto* p0> void g(Y<p0>); // C
template <auto** pp0> void g(Y<pp0>); // D
// primary class template template<class T, int I> struct A { void f(); }; // member of primary class template template<class T, int I> void A<T,I>::f() { } // class template partial specialization template<class T> struct A<T,2> { void f(); void g(); void h(); }; // member of class template partial specialization template<class T> void A<T,2>::g() { } // explicit specialization template<> void A<char,2>::h() { } int main() { A<char,0> a0; A<char,2> a2; a0.f(); // OK, uses definition of primary template's member a2.g(); // OK, uses definition of partial specialization's member a2.h(); // OK, uses definition of explicit specialization's member a2.f(); // ill-formed, no definition of f for A<T,2>; the primary template is not used here }— end example
template<class T> struct A {
template<class T2> struct B {}; // #1
template<class T2> struct B<T2*> {}; // #2
};
template<> template<class T2> struct A<short>::B {}; // #3
A<char>::B<int*> abcip; // uses #2
A<short>::B<int*> absip; // uses #3
A<char>::B<int> abci; // uses #1
— end example