Что касается стиля, вы можете выделить части, которые отличаются как тривиальный шаблонный класс, который более легко специализируется. В качестве примера этой техники рассмотрим реализацию вашего любимого шаблона неупорядоченного набора (или hash_set). Такие реализации требуют, чтобы вы специализировали простой шаблон hash_key , если специализация еще не доступна. Они не требуют, чтобы вы специализировали весь контейнер.
Хотя ваш пример достаточно прост, чтобы просто специализировать всю функцию, в целом я бы реализовал Func в общем и специализировал бы DoSomethingSpecial примерно так:
template< class T >
void DoSomethingSpecial(T &input)
{
...
}
template< class T >
void Func(T input)
{
DoSomethingGeneral1();
...
DoSomethingSpecial(T);
...
DoSomethingGeneral2();
}
template<>
void DoSomethingSpecial(std::string &input)
{
...
}
template<>
void DoSomethingSpecial(int &input)
{
...
}