Шаблоны не являются простым механизмом замены токенов, как макросы.const T
здесь не означает "вставьте меня туда, где T
сразу после const
".Это означает, что тип вещи "const
независимо от того, что T
есть".В случае шаблона вашей функции, если вы установите T
равным const char*
, тогда тип const T&
будет ссылкой на const
независимо от того, чем является T
, то есть ссылкой на const char*
, которыйсамо по себе const
, т. е. const char * const &
.Это на самом деле ничем не отличается от того, что если T
было именем, определенным с помощью typedef, а не параметром шаблона, например:
using T = int*;
const T blub = 42; // type of blub is int* const, not const int*
Следовательно,
template <>
void function(const char*& t1, const char*& t2);
не является действительной специализациейшаблон функции function
.Нет T
, который вы могли бы заменить в своем шаблоне function
, чтобы получить эту подпись.Если вы замените const char*
на параметр T
, т. Е. На форму function<const char*>
, его подпись будет иметь вид
void function<const char*>(const char * const& t1, const char * const& t2);
Обратите внимание, что вместо того, чтобы полагаться на явную специализацию, если вы хотите отдельнуюфункция для обработки случая
void function(const char*& t1, const char*& t2);
, просто добавьте такую функцию и полагайтесь на перегрузку, чтобы творить ее магию.В общем, когда вы пишете явную специализацию шаблонов функций, есть вероятность, что вы на самом деле хотели просто использовать перегрузку.См. Также Шаблон специализации VS Перегрузка функций или в этой статье (старая, но все еще такая же, как и прежде), чтобы узнать больше об этом ...