Во-первых: не существует такой вещи, как внешние шаблоны (в стандарте C ++ было ключевое слово экспорта, но оно было проигнорировано основными производителями компиляторов, такими как MS и GNU, и теперь кажется заброшенным).Поэтому вы должны поместить тела шаблонных функций в заголовочный файл.
Второе: лучше забудьте частичную специализацию шаблона.Он не поддерживается достаточно хорошо, например, MS обеспечивает очень ограниченную поддержку частичной специализации шаблонов классов (для указателей, ссылок, указателей на члены и указатели на функции (см. Здесь) ).Так что лучше просто не используйте его.Но вы можете использовать полностью явную специализацию шаблонов.
В-третьих: в вашем коде на самом деле нет шаблонизаций специализаций
template <class T>
Terminallog & operator<<(const T &v);
template <class T>
Terminallog & operator<<(const std::vector<T> &v);
template <class T>
Terminallog & operator<<(const T v[]);
- это три различных функциональных шаблона и
Terminallog & operator<<(const char v[]);
- это просто функция.
Правильный синтаксис для специализаций шаблонов функций таков:
template <class T>
Terminallog& out(const T& v)
{
// default implementation
}
template <class T>
Terminallog& out< std::vector<T> >(const std::vector<T>& v)
{
// partially specialized implementation
}
template <>
Terminallog& out<double>(const double& v)
{
// fully specialized implementation
}
Но это не совсем так.Разрешение перегрузки по-прежнему должно приводить к наиболее специализированной функции или шаблону функции (если такой функции не существует) в соответствии с правилами, определенными в стандарте.Но я не уверен, что существует полностью совместимая реализация C ++ (кроме Comeau C ++, разработанного стандартными авторами, никем не используемыми).Я думаю, что если у вас есть две перегрузки, которые точно совпадают или не соответствуют ни одной из них (и требуется неявное преобразование), у вас могут возникнуть проблемы с несоответствием.
ТАКЖЕ ПРИМЕЧАНИЕ:
Специализации шаблонов функций разрешены только в области имен.Это означает, что вы не можете объявлять специализации шаблона функции-члена.Но, конечно, вы можете определить перегрузки, как вы это сделали.