Презентация на тему "Шаблоны функций, специализация"

Презентация: Шаблоны функций, специализация
1 из 22
Ваша оценка презентации
Оцените презентацию по шкале от 1 до 5 баллов
  • 1
  • 2
  • 3
  • 4
  • 5
4.0
1 оценка

Комментарии

Нет комментариев для данной презентации

Помогите другим пользователям — будьте первым, кто поделится своим мнением об этой презентации.


Добавить свой комментарий

Аннотация к презентации

Скачать презентацию (0.08 Мб). Тема: "Шаблоны функций, специализация". Предмет: информатика. 22 слайда. Для студентов. Добавлена в 2017 году. Средняя оценка: 4.0 балла из 5.

Содержание

  • Презентация: Шаблоны функций, специализация
    Слайд 1

    Шаблоны функций, специализация

    Степанюк Константин Сергеевич 24const@gmail.com

  • Слайд 2

    Шаблоны функций

    template void sort(vector&); void f (vector& vi, vector &vs){ sort(vi); //sort(vector&) sort(vs); //sort(vector&) } При вызове шаблона функции аргументы могут однозначно определять какая версия шаблона используется. В этом случае говорят что аргументы шаблона функции выводятся по аргументам функции Компилятор может вывести аргументы как являющиеся типами так и обычные при условии, что список аргументов функции однозначно идентифицирует набор аргументов шаблона

  • Слайд 3

    Пример

    template T& lookup(Buffer&b, const char *p); class Record { const char[12]; //… }; Record& f(Buffer &buf, const char *p) { // вызвать lookup(), где T-Record, i -128 return lookup(buf,p); } //Иногда требуется указать аргумент явно: template T* create(); void f() { vector v; int *p = create(); }

  • Слайд 4

    Перегрузка шаблонов функций

    template T sqrt(T); template complex sqrt( complex); double sqrt(double); void f(complex z){ sqrt(2); //sqrt (int) sqrt(2.0); //sqrt(double) sqrt(z);//sqrt (complex) }

  • Слайд 5

    Правила разрешения перегрузки

    Ищется набор специализаций шаблонов функций, принимается решение какие аргументы были бы использованы, если бы в текущей области видимости не было других шаблонов функций и обычных функций с тем же именем (в примере –sqrt(complex) и sqrt>(complex) Если могут быть вызваны два шаблона функции и один из них более специализирован чем другой, на последующих этапах только он и рассматривается.(Для нашего примера предпочтение отдается sqrt(complex) по отношению к sqrt(complex) )

  • Слайд 6

    Разрешается перегрузка для данного набора функций, а также для любых обычных функций (в соответствии с правилами разрешения перегрузки для обычных функций). Если аргументы функции шаблона были определены путем выведения по фактическим аргументам шаблона, к ним нельзя применять «продвижение», стандартные и определяемые пользователем преобразования типа. (в нашем примере sqrt(int)является точным соответствием и поэтому ей отдается предпочтение по отношению к sqrt(double) Если и обычная функция и специализация подходят одинаково хорошо, то предпочтение отдается обычной функции (sqrt(double)а не sqrt(double)

  • Слайд 7

    Если ни одного соответствия не найдено или процесс оканчивается нахождением двух или более одинаково хорошо подходящими вариантами, то выдается соответствующая ошибка компиляции template T max (T, T); const int s = 7; void doIt() { max(1,2); // max(1,2) max('a','b'); // max('a','b') max(2.7,4.9); // max (2.7,4.9) max(s,7); //max(int(s), 7) –тривиальное преобр. max('a',1); //error –неоднозначность, стандартные //преобразования не применяются max(2.7,4); //error –неоднозначность }

  • Слайд 8

    Разрешение неоднозначности

    Явная квалификация: max(‘a’,1); // max (int(‘a’), 1) max(2.7,4) // max(2.7, double(4)) Добавление подходящих объявлений inline int max (inti, int j) {return max(i, j);} inline double max (double d1, double d2) { return max(d1, d2); } inline double max (int i, double d) { return max(i, d);} inline double max (double d, int i) { return max(d, i);} void f () { max(‘a’,1); //max (int ('a'), 1) max(2.7, 4); //max (2.7, double (4)) }

  • Слайд 9

    Перегрузка и наследование

    Правила перегрузки гарантируют, что функции шаблоны корректно взаимодействуют с наследованием: template class B {/*…*/}; template class D: public B {/*…*/}; template void f( B* ); void g (B *pb, D *pd) { f(pb); //f (pb) f(pd); //f (static_cast*>(pd)); }

  • Слайд 10

    Дополнительные аспекты разрешения

    Аргумент функции, не использующийся при выведении параметра шаблона рассматривается точно также, как аргумент функции, не являющейся шаблоном, и к нему применяются обычные правила преобразования для аргумента функции при перегрузке обычных функций: template intget_nth (C& p, int n); class Index { public: operator int(); }; void f (vector &v, short s, Index i) { int i1 = get_nth (v, 2); //точное соответсвие int i2 = get_nth (v, s); //short в int int i3 = get_nth (v, i); //Index в int }

  • Слайд 11

    Использование аргументов шаблона для выведения алгоритма

    template > int compare (const String& s1, const String& s2) { for (inti=0; i classCmp { public: static inteq (T a, T b) { return a==b; } static intlt (T a, T b) { return a str1, str2; //compare > (str1, str2); compare (str1,str2); compare > (wstr1, wstr2);

  • Слайд 12

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

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

  • Слайд 13

    Класс Vector – кандидат на специализацию

    template class Vector { T* v; intsz; public: Vector(); Vector(int); T& elem(inti) {return v[i];} T& operator[] (inti); void swap(Vector&); }; Vector vi; Vector vps; Vector vs; Vector vpc; Vector vpn;

  • Слайд 14

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

    template class Vector { void **p; intsz public: Vector(); Vector(int); void* &elem(inti) {return p[i];} void* &operator[] (inti) {return elem(i);} void swap(Vector&); //… }; Полная специализация –отсутствует параметр шаблона, который бы следовало задавать или который бы выводился при инстанцированиипри использовании специализации

  • Слайд 15

    Частичная специализация

    template class Vector : private Vector { public: typedef Vector Base; Vector():Base() {} explicit Vector(int): Base(i) {} T* &elem(inti) { return static_cast (Base::elem()); } T* &operator[] (inti) { return static_cast (Base::operator[](i)); } //… }; Vector vps; // -это , T –shape Vector vppi; // -это , T –int*

  • Слайд 16

    Правила объявлений для специализаций

    Общий шаблон должен быть объявлен прежде любой специализации Если программист специализирует где-нибудь шаблон, то эта специализация должна быть в области видимости при каждом использовании шаблона с типом, для которого он был специализирован Все специализации шаблона должны быть объявлены в том же пространстве имен что и сам шаблон Одна специализация считается более специализированной чем другая если каждый список аргументов соответствующий образцу первой специализации соответствует и второй специализации, но не наоборот Более специализированной версии будет отдаваться предпочтение в объявлениях объектов, указателей, а также при разрешении перегрузки

  • Слайд 17

    Пример, специализация функций

    //общийшаблон template class Vector; //частичная специализация template class Vector; //полная специализация template class Vector; template bool less (T a, T b) {return a bool less (const char *a, const char *b) { return strcmp(a,b)можно опустить: template bool less(const char *a, const char *b) { return strcmp(a,b)

  • Слайд 18

    Наследование и шаблоны

    Наследование реализации и обеспечение типобезопасного использования, например: template class Vector : private Vector{/*…*/}; Уточнение существующего шаблона (класса) или обобщение набора операций, например: template class CheckedVector : public Vector{/*…*/}; template class Basic_ops { public: bool operator==(const C&) const; bool operator!=(const C&) const; const C& derived() {return static_cast*this;} };

  • Слайд 19

    Пример использования

    template class Math_container :public Basic_ops > { public: size_t size() const; T& operator[] (size_t); const T& operator[](size_t) const; //… }; template boolBasic_ops::operator==(const C& a) const { if (derived().size() != a.size()) return false; for (inti = 0; i

  • Слайд 20

    Организация исходного кода

    Ранние компиляторы: Объявления и определения шаблонов размещаются в заголовочном файле Заголовочный файл включается во все единицы трансляции где используются данные шаблоны Современные компиляторы: Заголовочный файл включает только объявления шаблона, определение иго структуры и его специализаций (без определения членов шаблона) Определения членов шаблона размещаются в некоторой единице компиляции и предваряются ключевым словом export по аналогии со встраиваемыми (inline)функциями

  • Слайд 21

    Примеры кода

    Первый вариант //file out.h : #include template void out (const T &t) {std::err void out (const T&); //file out.cpp #include export template void out(const T &t) {…} //file user2.cpp –отсутствует зависимость от iostream #include “out.h”

  • Слайд 22

    Вопросы

    Какая лекция\тема понравилась Вам больше всего? Удовлетворяет ли Вас качество организации и проведения занятий? Как вы считаете, что следует изменить для улучшения качества усвоения материала? Планируете ли Вы в дальнейшем заниматься в сфере информационных технологий?

Посмотреть все слайды

Сообщить об ошибке