printШаблоны

printСпециализация

Можно специализировать (изменять реализацию) для определенных типов данных шаблон функции, отдельные методы шаблона класса или шаблон класса целиком.

При специализации функций и отдельных методов допускается только полная специализация. Перед определением специализации пишется template <>, а после имени функции или класса добавляется список аргументов основного шаблона в <>. Аналогичной функциональности можно добиться, если определить обычную функцию или перегрузить шаблон функции. Разница в том, что генерация кода для обычной функции будет происходить при компиляции её определения (т.е. всегда), а для шаблона и специализации – при первом использовании (инстанцировании). Разница между специализацией и перегрузкой шаблона чисто концептуальная.

Пример специализации шаблона функции:
template<>
inline const char * maximum<const char *>(const char *a, const char * b)
{ return strcmp(a,b)>0?a:b;
}

Специализация шаблона класса определяется как шаблон класса, но нельзя указывать значения по умолчанию для параметров шаблона, а после имени класса указывается список аргументов основного шаблона в <>, который позволяет компилятору установить связь между параметрами специализации и основного шаблона. При специализации шаблона класса можно полностью изменить весь интерфейс класса. Допустима частичная специализация шаблона класса.

Пример специализации шаблона класса:
template <int size> // частичная специализация
class Stack<char *,size> {
  char *s[size]; 
  int t;
public:
  Stack():t(-1) {} // встраиваемые методы
  bool isEmpty() { return t==-1; }
  bool isFull() { return t==size-1; }
  ~Stack() { while(!isEmpty()) pop(); }
  void pop();
  const char * top();
  void push(const char *);
};
template <int size>
void Stack<char *,size>::pop()
{ if(!isEmpty())
    delete[] s[t--];
}
template <int size>
const char * Stack<char *,size>::top()
{ if(isEmpty())
    throw StackEmpty(); 
  return s[t];
}
template <int size>
void Stack<char *,size>::push(const char *v)
{ if(isFull())
    throw StackFull(); // сообщаем об ошибке
  s[++t]=new char[strlen(v)+1];
  strcpy(s[t],v);
}

loading