Home > Net >  Partial ordering of cv qualifiers vs pointer/reference in template specialization
Partial ordering of cv qualifiers vs pointer/reference in template specialization

Time:12-10

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
  • Related