Когда вам нужно параметризовать концепцию, представленную классом.
Например, если у вас есть класс, представляющий способ управления типом объекта
class MyThingManager
{
void add( MyThing& mything );
//...
};
... может позже вам понадобится использовать точно такое же поведение в новом типе, но управлять другим типом. Тогда у вас есть выбор использовать копирование / вставку / замену - это немедленно приведет к открытию ада под ногами - или у вашего класса будет тип для управления в качестве параметра:
template< class ThingType >
class ThingManager
{
void add( ThingType& thing );
//...
};
Таким образом, вы не дублируете код.
Другая проблема заключается в том, что вы хотите, чтобы какой-то вызов функции был совместим с любым параметром, который имеет требуемую семантику:
template< class MyType >
void addPi( MyType& value )
{
value += PI;
}
Таким образом, вам (опять же) не нужно дублировать код для каждого возможного типа в параметрах.
Это не называется "общим программированием" даром.
Это простые случаи, но существуют более сложные случаи, когда вы хотите заняться метапрограммированием. Если вы хотите пойти туда, пожалуйста, прочитайте хотя бы одну книгу, прежде чем писать адский код. Для этого я рекомендую «Мета-программирование шаблонов C ++» и отличную книгу «Современный дизайн C ++» для более сложного использования шаблонов, таких как шаблон политики и другие хорошо известные.