Say I have a class template with some specializations
template<typename T> struct A {};
template<typename T> struct A<T const> {};
template<typename T> struct A<T &> {};
Which specialization has the precedence, when I instantiate A<const int&>
?
I ran a test with GCC, and it picks the int&
specialization. I assume this is the rule, but I can't find where this is stated.
CodePudding user response:
X&
and const Y
can’t ever be decompositions of the same type, since references can’t be const-qualified. (Given using R=T&;
, const R
is the same type as R
, but that doesn’t mean that it has that qualifier to match anything.) As such, no ordering is needed, since the two specializations are disjoint.
CodePudding user response:
Lets look at what is happening.
Statement 1
template<typename T> struct A {}; //primary template
The above shown statement defines a primary template. This means that it can be used for any type.
Statement 2
template<typename T> struct A<T const> {};//specialized for T const
The above statement is a specialization of the primary template. This means, we are specializing for T const
. That is, this specialization will be used for template arguments having a top-level const.
Statement 3
template<typename T> struct A<T &> {};//specialized for T&
This time we are specializing the primary template for template argument of the form T&
. That is, we are specializing the primary template for lvalue references. Further, the lvalue reference can be a reference to const or a reference to nonconst. This means, this specialization will be used for all lvalue references(both T&
and const T&
).
Now lets come back to your question:
Which specialization has the precedence, when I instantiate A<const int&>?
When we write
A<const int&>
then since we already have a speciazation for lvalue references, that particular speciazation is used as i already explained in statement 3's explanation.
Some more examples
const int i = 5;
A<decltype(i)> p;//this will use the T const specialization since the template argument has a top level const