Лекция 22. Шаблоны (часть 2) презентация

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

Слайд 1Лекция 22. Шаблоны (часть 2)
Красс Александр
Alexander.Krass@gmail.com

СПбГУ ИТМО, 2008


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


Слайд 3Неполное инстанцирование
Рассмотрим шаблонную функцию возведения в степень:
template < unsigned N, typename

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


Слайд 4Полная специализация
Рассмотрим пример функции сравнения двух величин:
template < typename T >
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”); // Будет ли это работать правильно?



Слайд 5Полная специализация (2)
Для последнего примера функция будет выглядеть так:
bool less (

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


Слайд 6Полная специализация (3)
Можно пойти двумя путями:
Перегрузка:
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; }
Теперь наш пример работает правильно
Для функций перегрузка и полная явная специализация шаблона эквиваленты. Но для классов понятия перегрузки нет.

Слайд 7Полная специализация (4)
Пример из STL:
Обобщенная версия
template
class vector { …

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


Слайд 8Факториал на этапе компиляции
Классический пример из области шаблонов:
template < unsigned N

>
unsigned long Fact ( void )
{
if ( N<2 ) return 1;
return N*Fact();
}
Работать не будет!

Слайд 9unsigned long f5 = Fact();
template
unsigned long Fact ( void )
{
if (

3<2 ) return 1;
return 3*Fact<3-1>();
}
template<>
unsigned long Fact<2> ( void )
{
if ( 2<2 ) return 1;
return 2*Fact<2-1>();
}

template<>
unsigned long Fact<1> ( void )
{
if ( 1<2 ) return 1;
return 1*Fact<1-1>();
}
template<>
unsigned long Fact<0> ( void )
{
if ( 0<2 ) return 1;
return 0*Fact<0-1>();
}


Факториал на этапе компиляции (2)

Получаем бесконечную рекурсию!


Слайд 10Факториал на этапе компиляции (3)
А вот так работать будет:
Обобщенная версия
template

unsigned N >
unsigned long Fact ( void )
{ return N*Fact(); }
2. Явная специализация для частных случаев:
template<>
unsigned long Fact<0> ( void )
{ return 1; }
template<>
unsigned long Fact<1> ( void )
{ return 1; }


Слайд 11unsigned long f5 = Fact();

template
unsigned long Fact ( void )
{ return

3*Fact<3-1>(); }

template<>
unsigned long Fact<2> ( void )
{ return 2*Fact<2-1>(); }

template<>
unsigned long Fact<1> ( void )
{ return 1; }

Факториал на этапе компиляции (4)

Процесс остановился. Все работает.


Слайд 12typename
Имеем класс:
class C
{
public:
typedef int SomeType;
};
Определяем шаблонную функцию:
template
void f()
{

T::SomeType *var; // будет ли это компилироваться?
}
Компилятор может это распознать или как объявление указателя на тип T::SomeType или как умножение T::SomeType на var. Следовательно, будет ошибка компиляции.


Слайд 13typename (2)
Таким образом при использовании в шаблоне члена класса мы должны

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

Слайд 14Домашнее задание 1
Реализовать вычисление факториала на этапе компиляции с помощью следующей

конструкции:

template
struct Fact
{
const static int value = . . .
};


Слайд 15Домашнее задание 2
На основе реализованного на прошлой лекции класса Stack написать

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

Обратная связь

Если не удалось найти и скачать презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:

Email: Нажмите что бы посмотреть 

Что такое ThePresentation.ru?

Это сайт презентаций, докладов, проектов, шаблонов в формате PowerPoint. Мы помогаем школьникам, студентам, учителям, преподавателям хранить и обмениваться учебными материалами с другими пользователями.


Для правообладателей

Яндекс.Метрика