Я подозреваю, что кто-то должен сказать вам, почему не стоит использовать перегрузку или специализацию. Рассмотрим:
template<class T> int foo(T a) {
if(isAString<T>()) {
return a.length();
} else {
return a;
}
}
На первый взгляд вы можете подумать, что он будет работать и для int
, потому что он будет пытаться вызвать length
только для строк. Но эта интуиция ошибочна: компилятор все еще проверяет ветвь строки, даже если эта ветвь не берется во время выполнения. И он обнаружит, что вы пытаетесь вызвать функцию-член для неклассов, если T
является целым числом.
Вот почему вы должны отделить код, если вам нужно другое поведение. Но лучше использовать перегрузку, а не специализацию, поскольку легче понять, как с ней работают.
template<class T> int foo(T a) {
return a;
}
int foo(std::string const& a) {
return a.length();
}
Вы также лучше разделили код для разных путей поведения. Это больше не все вместе. Обратите внимание, что при перегрузке параметры могут иметь разные формы типов, и компилятор будет по-прежнему использовать правильную версию, если обе совпадают одинаково хорошо, как в данном случае: один может быть ссылкой, а другой - нет.