Seoul
Seoul

Reputation: 605

Template Specialization with Default Value

This is the code I am working with:

#include <iostream>
#include <type_traits>

using namespace std;

using match_type = void;
using match_type_bad = int;

// version A
template <typename T, typename Attempt = match_type>
struct simple_check : false_type {}; 

// version B
template <typename T>
struct simple_check<T, T> : true_type {}; 

int main() {
  cout << simple_check<match_type>::value << endl;
  cout << simple_check<match_type_bad>::value << endl;
}

The program with this template specialization ends up having the output as:

1
0

There is a confusion in my understanding of C++'s tmp as I was assuming that the output should have been 1 1.

My reasoning was:

  1. With simple_check<match_type> it goes into version B and then gets expanded to simple_check<match_type, match_type> which inherits from true_type. So 1 as expected.

  2. Shouldn't the same apply to simple_check<match_type_bad>?

  3. With this logic, any type X into simple_check<X> should always be version B.

It seems that version A's default value of match_type is enforcing some rule when it decides on version B.

Why is version A affecting version B? Possibly something else?

Upvotes: 4

Views: 184

Answers (1)

super
super

Reputation: 12968

When you instatiate a template it always uses the base version before looking at the specializations. It works here since the second template parameter has a default value of match_type.

So

simple_check<match_type> => simple_check<match_type, match_type>
                                                     ^^ this uses the default value

simple_check<match_type_bad> => simple_check<match_type_bad, match_type>
                                                             ^^ again, default value

After this is done, the compiler looks at the specializations.
The specialization only works if the template parameters are the same, so for the first check the specialization will be chosen over the base template, and for the second the base template will be used since the specialization is not valid.

Upvotes: 7

Related Questions