Лекция 22. Шаблоны (часть 2) Красс Александр Alexander.Krass@gmail.com СПбГУ ИТМО, 2008.

Презентация:



Advertisements
Похожие презентации
Лекция 23. Шаблоны (часть 3) Красс Александр СПбГУ ИТМО, 2008.
Advertisements

Преобразования типов В языке C/C++ имеется несколько операций преобразования типов. Они используются в случае, если переменная одного типа должна рассматриваться.
Лекция 21. Шаблоны (часть 1) Красс Александр СПбГУ ИТМО, 2008.
Объектно-ориентированное программирование С++. Лекция 8 Карпов В.Э.
Обработка исключений Основы метапрограммированияОбработка исключений Основы метапрограммирования.
Лекция 9. Введение в ООП. Часть 2 Красс Александр СПбГУ ИТМО, 2008.
Лекция 13. Введение в ООП. Часть 4 Красс Александр СПбГУ ИТМО, 2008.
Лекция 10. Введение в ООП. Часть 3 Красс Александр СПбГУ ИТМО, 2008.
Функции Функция – именованная последовательность описаний и операторов, выполняющая некоторое действие. Может иметь параметры и возвращать значение. Функция.
Лекция 2. Фундаментальные типы данных и основные конструкции Красс Александр СПбГУ ИТМО, 2008.
Лекция 6 Функции. Объявления и определения Объявление функции – указание имени функции, а также входных и выходных параметров Определение функции – указание.
Лекция 8. Введение в ООП. Часть 1 Красс Александр СПбГУ ИТМО, 2008.
Шаблоны 1. Механизм шаблонов реализует в С++ параметрический полиморфизм. 2. Шаблон представляет собой предварительное описание функции или класса, конкретное.
Лекция 6 Функции. Объявления и определения Объявление функции – указание имени функции, а также входных и выходных параметров Определение функции – указание.
1 Введение в С++11 (стандарт ISO/IEC 14882:2011 ) Вне рассмотрения в рамках курса остаются нововведения для работы с шаблонами: ведение понятий лямбда-функций.
Лекция 14 Динамические данные. Виды памяти Существует три вида памяти: статическая, стековая и динамическая. Статическая память выделяется еще до начала.
Обработка исключительных ситуаций Исключительная ситуация (исключение) – это ошибка, возникающая во время выполнения программы. Например, ошибка работы.
Лекция 11. Введение в ООП. Часть 4 Красс Александр СПбГУ ИТМО, 2008.
Лекция 4. Введение в С++ Наследование, множественное наследование. Конструкторы, деструкторы. Виртуальные функции.
Практическое занятие 6. Функции. Большинство языков программирования используют понятия функции и процедуры. C++ формально не поддерживает понятие процедуры,
Транксрипт:

Лекция 22. Шаблоны (часть 2) Красс Александр СПбГУ ИТМО, 2008

Темы Неполное инстанцирование Полная специализация Факториал на этапе компиляции typename

Неполное инстанцирование Рассмотрим шаблонную функцию возведения в степень: template T Power ( T v ) { T res = v; for ( int i=1; i<N; i++ ) res *= v; return res; } Функцию Power можно вызвать двумя способами: 1. int r = Power (1); 2. int r = Power (1); // Вот это и есть не полное инстанцирование. Компилятор самостоятельно выводит недостающие аргументы шаблона

Полная специализация Рассмотрим пример функции сравнения двух величин: template bool less ( T v1, T v2 ) { return v1 < v2; } Примеры использования: bool l1 = less(1,2); bool l2 = less(1.2,3.4); bool l4 = less(abcd,abcx); // Будет ли это работать правильно?

Полная специализация (2) Для последнего примера функция будет выглядеть так: bool less ( char* v1, char * v2 ) { return v1 < v2; // сравнение указателей, а не строк!!! } Итого: 1. Мы хотим иметь обобщенную форму less 2. Версию сравнения строк.

Полная специализация (3) Можно пойти двумя путями: 1.Перегрузка: bool less(const char *s1, const char *s2) { return strcmp(s1, s2) < 0; } 2. Явная специализация шаблона: template<> bool less ( const char* s1, const char* s2 ) { return strcmp(s1,s2)<0; } Теперь наш пример работает правильно Для функций перегрузка и полная явная специализация шаблона эквиваленты. Но для классов понятия перегрузки нет.

Полная специализация (4) Пример из STL: Обобщенная версия template class vector { … }; - динамический массив Специализация template<> class vector { …}; - массив флагов, каждый флаг это один бит. Реализовано в целях оптимизации по памяти.

Факториал на этапе компиляции Классический пример из области шаблонов: template unsigned long Fact ( void ) { if ( N<2 ) return 1; return N*Fact (); } Работать не будет!

unsigned long f5 = Fact (); template<> unsigned long Fact ( void ) { if ( 3<2 ) return 1; return 3*Fact (); } template<> unsigned long Fact ( void ) { if ( 2<2 ) return 1; return 2*Fact (); } template<> unsigned long Fact ( void ) { if ( 1<2 ) return 1; return 1*Fact (); } template<> unsigned long Fact ( void ) { if ( 0<2 ) return 1; return 0*Fact (); } Факториал на этапе компиляции (2) Получаем бесконечную рекурсию!

Факториал на этапе компиляции (3) А вот так работать будет: 1. Обобщенная версия template unsigned long Fact ( void ) { return N*Fact (); } 2. Явная специализация для частных случаев: template<> unsigned long Fact ( void ) { return 1; } template<> unsigned long Fact ( void ) { return 1; }

unsigned long f5 = Fact (); template<> unsigned long Fact ( void ) { return 3*Fact (); } template<> unsigned long Fact ( void ) { return 2*Fact (); } template<> unsigned long Fact ( void ) { return 1; } Факториал на этапе компиляции (4) Процесс остановился. Все работает.

typename Имеем класс: class C { public: typedef int SomeType; }; Определяем шаблонную функцию: template void f() { T::SomeType *var; // будет ли это компилироваться? } Компилятор может это распознать или как объявление указателя на тип T::SomeType или как умножение T::SomeType на var. Следовательно, будет ошибка компиляции.

typename (2) Таким образом при использовании в шаблоне члена класса мы должны явно указывать, что из себя представляет этот член: –Если это тип, то перед ним надо указывать typename typename T::SomeType *var; –Если это не тип, то typename указывать не нужно.

Домашнее задание 1 Реализовать вычисление факториала на этапе компиляции с помощью следующей конструкции: template struct Fact { const static int value =... }; 14

Домашнее задание 2 На основе реализованного на прошлой лекции класса Stack написать решение задачи о Ханойских башнях. Каждый стержень – это экземпляр класса Stack. Параметр шаблона стека T – это класс Disk, имеющий поле diameter. Программа должна уметь выдавать пользователю содержание всех трёх стержней в любой указанный пользователем момент времени (пример: через 50 перекладываний). 15