For two partial specializations,
the first is more specialized than the second if, given the following
rewrite to two function templates, the first function template is more
specialized than the second according to the ordering rules for function
templates:
Each function template
has a single function parameter
whose type is a class template specialization where the template arguments
are the corresponding template parameters from the function template
for each template argument
in the template-argument-list
of the simple-template-id
of the partial specialization.
[Example 1: template<int I, int J, class T>class X {};
template<int I, int J>class X<I, J, int>{}; // #1template<int I>class X<I, I, int>{}; // #2template<int I0, int J0>void f(X<I0, J0, int>); // Atemplate<int I0>void f(X<I0, I0, int>); // Btemplate<auto v>class Y {};
template<auto* p>class Y<p>{}; // #3template<auto** pp>class Y<pp>{}; // #4template<auto* p0>void g(Y<p0>); // Ctemplate<auto** pp0>void g(Y<pp0>); // D
According to the ordering rules for function templates,
the function template
B
is more specialized than the function template
A
and
the function template
D
is more specialized than the function template
C.
Therefore, the partial specialization #2
is more specialized than the partial specialization #1
and the partial specialization #4
is more specialized than the partial specialization #3.
— end example]
[Example 2: template<typename T>concept C =requires(T t){ t.f(); };
template<typename T>concept D = C<T>&&requires(T t){ t.f(); };
template<typename T>class S {};
template<C T>class S<T>{}; // #1template<D T>class S<T>{}; // #2template<C T>void f(S<T>); // Atemplate<D T>void f(S<T>); // B
The partial specialization #2 is more specialized than #1
because B is more specialized than A.