Лекции по СП, страница 7
Описание файла
Документ из архива "Лекции по СП", который расположен в категории "". Всё это находится в предмете "практикум (прикладное программное обеспечение и системы программирования)" из 4 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Онлайн просмотр документа "Лекции по СП"
Текст 7 страницы из документа "Лекции по СП"
Пример такой ситуации.
template<class T, class U> T convert (U u) { ... return t; };
void g (int i){
convert (i); // U = int; T – непонятно
}
Надо учитывать, что при поиске соответствия компилятор не обращает внимания на то, чему мы присваиваем результат работы функции. Контекст не рассматривается!
Из этой ситуации можно выйти так:
convert<double> (i); // U = int; T = double
При спецификации типа указанный тип подставляется на место первого параметра, если указаны два типа – на место первого и второго, и так далее.
Мы можем придать новый смысл функции, например, заставить искать максимальный элемент в массиве. Для этого перегрузим её так:
template<class T > T max (T *p, int size) { ... };
А сможем ли мы искать с помощью нашей шаблонной функции максимум среди об’ектов класса Complex, описанного нами выше? То есть, можно ли написать так:
Complex a(1,2), b(3,4);
max (a,b); // T = Complex
Проблема, очевидно, в том, что в классе не определены операции сравнения. Однако у ТВ как-то получилось это скомпилировать (правда, в Microsoft Visual Studio). Программа даже запустилась и выдала результат! Но результат совершенно не подвластен здравому смыслу. Вы можете попробовать сделать то же самое в g++ и если что покопаться в исходниках и удовлетворить всеобщий интерес рассказом о том, что там происходит.
Вообще, к сожалению, компиляторы далеко не всегда хорошо держат стандарт при работе с шаблонами.
Шаблоны классов.
Шаблоны классов тоже зачастую бывают разумными. Как правило, они применяются при описании контейнеров, то есть типов, которые содержат в себе каким-то образом структурированные об’екты других типов. Например, стек можно реализовать как контейнер. Операции над ним, вообще говоря, не зависят от типа его элементов.
Пример. Контейнер-вектор.
template<class T> class Vector {
T *p;
int size;
public: explicit Vector (int);
T& operator[] (int i);
};
Vector<int> x(20); // вектор из 20 целых чисел
Vector<Complex> y(100); // вектор из 20 комплексных чисел
Инстанцирование – процесс генерации класса по шаблону.
Любая функция из шаблонного класса является шаблонной, так что описывать функции вне класса нужно так:
template<class T> T& Vector<T>::operator[] (int i) { ... }
Пример. Класс с нетиповым параметром.
template<class T, int size> class buffer { ... }
buffer <char,1024> x;
buffer <char,512*2> y;
buffer <int,1024> z;
Возникает вопрос, какие переменные будут иметь одинаковые типы? Есть общее правило: инстанцированные классы будут считаться одинаковыми, если типовые параметры совпадают, а нетиповые равны по значению. x и z, очевидно, разного типа, так как типовые параметры не совпадают. Для нетиповых параметров должна быть определена операция сравнения на равенство. Получается, что параметры шаблона не могут быть вещественными.
Еще одно замечание: нетиповые параметры могут быть только у шаблонов классов, но не у шаблонов функций (так сказала ТВ; но как быть со вставкой выше?).
/* на этом изложение теории языка C++ считается законченным. На лекциях ещё будет рассказ о STL, но это хз когда. */
Удачи всем в субботу! ;)