В чем разница между Template Explicit Specialization и обычной функцией?

template <class T>
void max (T &a ,T &b)
{}//generic template   #1

template<> void max(char &c, char &d)
{} //template specializtion    #2

void max (char &c, char &d)
{}//ordinary function      #3

какая разница между 1, 2 и 3?

Ответ 1

  • - это функция шаблона
  • - полная специализация предыдущей функции шаблона (не перегружает!)
  • является перегрузкой функции

Вот выдержка из Стандарты кодирования С++: 101 Правила, рекомендации и лучшие практики:

66) Не специализируйте шаблоны функций

Специализация шаблонов функций никогда не участвует в перегрузке: поэтому любые специализированные записи, которые вы пишете, не будут влиять на используемый шаблон, и это противоречит тому, что интуитивно ожидало бы большинство людей. В конце концов, если бы вы написали функцию nontemplate с идентичной подписью вместо специализации шаблона функции, функция nontemplate всегда была бы выбрана, потому что она всегда считалась лучшим совпадением, чем шаблон.

В книге предлагается добавить уровень косвенности путем реализации шаблона функции в терминах шаблона класса:

#include <algorithm>

template<typename T>
struct max_implementation
{
  T& operator() (T& a, T& b)
  {
    return std::max(a, b);
  }
};

template<typename T>
T& max(T& a, T& b)
{
  return max_implementation<T>()(a, b);
}

См. также:

Ответ 2

Правила сопоставления параметров шаблона тонко отличаются от правил перегрузки. Пример того, что отличается, можно увидеть, когда вы пытаетесь вызвать max() с аргументами разных tyoes:

max(1,'2');

Это будет соответствовать перегруженной функции, но ни базовый шаблон, ни специализация.