2

This answer explains the behaviour of the following program:

template<typename A, typename B = int > struct FirstWins { static constexpr int i = 1; }; template<typename A> struct FirstWins<A, float/* anything different from int */ > { static constexpr int i = 2; }; template<typename A, typename B = int > struct SecondWins { static constexpr int i = 1; }; template<typename A> struct SecondWins<A, int > { static constexpr int i = 2; }; int main() { typedef void Whatever_t; cout << FirstWins < Whatever_t >::i << endl; // prints 1 cout << SecondWins< Whatever_t >::i << endl; // prints 2 return 0; } 

However, I cannot find an actual reference describing explicitly this behaviour and thus confirming the answer.

I could not find on cppreference.com a sentence confirming that explicit template arguments are preferred over default ones.

I suspect that this is not really the rule. The rule is that whenever there is a partial template specialization matching the template arguments, that specialization is always chosen over the instantiation of the primary template. Is this correct? (in this case, the docs somehow explain this rule, but again not explicitly).

6
  • 2
    A default parameter just supplies a type when the code doesn't. It has no effect on selecting the specialization. Commented Jun 7, 2018 at 13:08
  • 2
    I think you're confused about what default template arguments are used for. In your example, it just means that FirstWins<X> resolves as FirstWins<X, int>. The actual selection of the definition of FirstWins<X, int> happens after the "substitution" of B for int. Commented Jun 7, 2018 at 13:09
  • @Holt: sure, but my question really pertains SecondWins<X, int>. In that case, SecondWins<X, int> is preferred over SecondWins<X, =int>. Commented Jun 7, 2018 at 14:38
  • @L.Bruce Because SecondWins<A, B=int> is no different than SecondWins<A, B> for template selection, and so the specialization SecondsWins<A, int> is preferred over the non-specialized one. The default template argument has no impact here for the resolution. Commented Jun 7, 2018 at 14:39
  • @Holt: Well, in a way it does have impact, I believe. Look at FirstWins. There it is the mismatch between the default parameter B=int and the explicit one float that leads to the selection of the first. B defaulting to anything that is not float does make the difference. Commented Jun 7, 2018 at 15:24

1 Answer 1

0
template<typename A, typename B = int > struct S { //... }; 

Can be seen as

template<typename A, typename B = int > struct S; // So S<A> is S<A, int> // Primary template template<typename A, typename B> struct S { //... }; // Possible specialization as template<typename A> struct S<A, int> { //... }; 

then, it is more clear which instantiation to use.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.