-2

Case 1 The possible implementation of std::remove_const is

template< class T > struct remove_const          { typedef T type; };
template< class T > struct remove_const<const T> { typedef T type; };

When i use them

std::remove_const<int> // use the first version
std::remove_const<const int> // use the second version

Case 2 If i comment the second version

template< class T > struct remove_const          { typedef T type; };
//template< class T > struct remove_const<const T> { typedef T type; };

And use them

std::remove_const<int> // use the first version
std::remove_const<const int> // use the first version

In the Case 1 , how does compiler decide to choose the second version for const int ?

sanjay
  • 735
  • 1
  • 5
  • 23
  • Somewhat related: https://stackoverflow.com/q/35652212/1896169 – Justin Sep 27 '17 at 19:20
  • 2
    I think you're asking how partial template specialization works. It's complicated, but this wiki is a decent overview: http://en.cppreference.com/w/cpp/language/partial_specialization . The short answer is `const int` is a closer match to `const T` than plain-old-`T`, so it is preferred. – Travis Gockel Sep 27 '17 at 19:20
  • @TravisGockel Thanks for the link. I have read about the Template Specialization. But example I saw, use specialization for completely different type ( for e.g. int, float, short) but not with closely related types ( e.g. int and const int). Thanks for the info – sanjay Sep 27 '17 at 19:30
  • Of course there is a standard for it. An ISO standard to be exact. While the official publication is proprietary, the last drafts prior to publication are available to the public (and are nearly identical to the finished document). – StoryTeller - Unslander Monica Sep 27 '17 at 19:35
  • On a related note you shouldn't really use `remove_const` in your code. 99 times out of 100, if you are then you're probably doing something wrong. – quantik Sep 27 '17 at 20:32

2 Answers2

3

Specialization.

The const T version is more specialized than the generic version (because if a type match const T, match the generic T also; int match T but not const T).

The rule is that if a type match two or more versions, the compiler must choose the more specialized one.

max66
  • 65,235
  • 10
  • 71
  • 111
2

This is not two different versions of a template. This is a single template (what you call the first version), with a specialization defined (what you call the second version).

So when you use the template it always first finds the definition of the template, and then looks for preexisting specializations and instantiations of the template that match the type signature you are using. If it finds a specialization (or instantiation) that matches, it uses that. Only if there is no existing specialization or instantiation does it instatiate the template.

So when you say remove_const<int> it matches the template, but does not match the specialization, so it instantiates the template. remove_const<const int> matches the template and also matches the specialization, so it uses the specialization (which is also a template, so needs to be instantiated, but that is secondary).

The thing that makes your "second version" a specialization rather than a new template is the <..> list after the name remove_const.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226