mathk
mathk

Reputation: 8133

Getting confused with C++ template

I am looking at some c++ code and do not understand the purpose of the template declaration in this situation:

template<> void operator>>(const ClassA& s, const ClassB d) {...}

What is the semantic of template<>?

Upvotes: 2

Views: 316

Answers (4)

Gorpik
Gorpik

Reputation: 11028

This is, indeed, template specialization, as others before mentioned. There must be some previously declared function template, such as:

template<typename T, typename U>
void operator>>(const T& s, const U d) {...}

However, it is quite misguided. It is much better to remove the template<> altogether, so operator>> would just be overloaded. The problem with function template specialization is that it may lead to unexpected behaviour in the presence of overloaded functions (and operator>> has lots of overloads), since the specialization does not overload. This means that the compiler first selects the most appropriate overload for the function and then, if the selected overload is a function template, it looks for template specializations to see if there is an appropriate one.

A classical example (unfortunately, I don't remember where I read it). Consider this overloaded function template:

template <typename T>
void Function(T param);

template <typename T>
void Function(T* param);

template <>
void Function(int* param);

main()
{
  int i = 5;
  Function(&i);
}

As expected, the template specialization for int* is called. But just change the order of the function definitions:

template <typename T>
void Function(T param);

template <>
void Function(int* param);

template <typename T>
void Function(T* param);

main()
{
  int i = 5;
  Function(&i);
}

Now the general template for T* is called, since we are specializing the template for T, not for T*, and this second template is better suited for our call. This would be avoided if we overloaded the function instead of specializing the template:

void Function(int* param);

Now the order of declaration does not matter, we will always call the overload for int*.

UPDATE: Now I know who to credit. I read about this in an article by Herb Sutter. The example was provided by Peter Dimov and Dave Abrahams.

Upvotes: 11

P&#233;ter T&#246;r&#246;k
P&#233;ter T&#246;r&#246;k

Reputation: 116266

It is a template specialization: (fully or partially) resolving the template for a specific type. (Your particular example seems to be a full specialization, as no more template parameters are left unresolved in it. If the template has multiple parameters, and you specialize only some of them, it is called partial template specialization)

This allows one to provide type-specific optimizations for a given template, or to do many clever tricks such as detecting the static type of variables etc.

Upvotes: 2

Andres Jaan Tack
Andres Jaan Tack

Reputation: 23014

You use this syntax when you want to provide a special handler for a particular template type. Consider:

// A normal template definition.
template <typename AType>
whoami () {   std::cout << "I am an unknown type.";  }

// Now we specialize.
template <>
whoami<int> () {   std::cout << "I am an integer!";  }

There's some other nonsense involved, particularly "partial specialization", but that's the basic function of template <>.

Upvotes: 2

Kiril Kirov
Kiril Kirov

Reputation: 38163

This is Template specialization

Upvotes: 2

Related Questions