if (v2 < v1) return 1;

 return 0;

}

Определение шаблона начинается с ключевого слова template, за которым следует разделяемый запятыми и заключенный в угловые скобки (<>) список параметров шаблона (template parameter list), один или несколько параметров шаблона (template parameter).

Список параметров в определении шаблона не может быть пустым

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

Аналогично параметры шаблона представляют типы или значения, используемые при определении класса или функции. При использовании шаблона необходимо (явно или неявно) определить аргументы шаблона (template argument), чтобы связать их с соответствующими параметрами шаблона.

Например, рассматриваемая функция compare() объявляет единственный параметр типа Т. В шаблоне compare имя Т можно использовать там, где должно быть название типа данных. Фактический тип Т будет определен компилятором на основании способа применения функции.

Создание экземпляра шаблона функции

Когда происходит вызов шаблона функции, для вывода типов аргументов шаблона компилятор обычно использует аргументы вызова. Таким образом, когда происходит вызов шаблона compare, компилятор использует тип аргументов для определения типа, связанного с параметром шаблона Т. Рассмотрим следующий вызов:

cout << compare(1, 0) << endl; // Т - тип int

Здесь аргумент имеет тип int. Компилятор выведет и использует тип int как аргумент шаблона, а также свяжет этот аргумент с параметром Т шаблона.

При создании экземпляра (instantiation) специфической версии функции компилятор сам использует выведенные параметры шаблона. При этом он подставляет фактические аргументы шаблона вместо соответствующих параметров шаблона. Рассмотрим следующий вызов:

// создание экземпляра int compare(const int&, const int&)

cout << compare(1, 0) << endl; // T - тип int

// создание

// экземпляра int compare(const vector&, const vector&)

vector vec1{1, 2, 3}, vec2{4, 5, 6};

cout << compare(vec1, vec2) << endl; // T - тип vector

Здесь компилятор создает два экземпляра разных версий функции compare(). В первой из них параметр Т заменен типом int.

int compare(const int &v1, const int &v2) {

 if (v1 < v2) return -1;

 if (v2 < v1) return 1;

 return 0;

}

Во втором вызове создается версия функции compare() с параметром Т, замененным типом vector. Такое создание компилятором функций обычно и называют созданием экземпляра шаблона.

Параметры типа шаблона

У функции compare() есть один параметр типа (type parameter) шаблона. Как правило, параметр типа можно использовать как спецификатор типа таким же образом, как и встроенный спецификатор типа или класса. В частности, параметр типа применим при назначении типа возвращаемого значения или типа параметра функции, а также в объявлениях переменных или приведениях в теле функции:

// ok: для возвращаемого значения и параметра используется тот же тип

template Т foo(Т* p) {

 Т tmp = *p; // тип tmp совпадает с типом, на который указывает p

 // ...

 return tmp;

}

Каждому параметру типа должно предшествовать ключевое слово class или typename:

// ошибка: U должно предшествовать либо typename, либо class

template Т calc(const T&, const U&);

В списке параметров шаблона эти ключевые слова имеют одинаковый смысл и применяются взаимозаменяемо. Оба ключевых слова применимы одновременно:

// ok: в списке параметров шаблона нет никакой разницы между ключевыми

// словами typename и class

template calc(const T&, const U&);

Перейти на страницу:

Похожие книги