Файл: Pobegaylo_A._C_Cplus_dlya_studenta.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 13.12.2020

Просмотров: 4172

Скачиваний: 28

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

  

 
 

Г Л А В А  

18 

 
 
 

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

 

18.1. Определение шаблона  

функции 

Функция, которая абстрагируется от типа хотя бы одного из сво-
их  параметров,  называется 

обобщенной 

или

  родовой 

(generic)

 

функцией

. В языке программирования С++ родовые функции оп-

ределяются 

шаблонами функций

Определение шаблона функции имеет следующий вид: 

  template <список_параметров> 
  определение_функции 

В угловых скобках указан список параметров шаблона функции, 
который не может быть пустым. Параметрами шаблона функции 
могут быть: 

 

типы; 

 

не типы; 

 

шаблоны класса. 

Объявление параметра-типа шаблона имеет следующий вид: 

  class|typename имя_параметра 

Ключевые слова 

class

  и 

typename

  являются  взаимозаменяемыми. 

В качестве аргумента для параметра-типа запрещается использо-
вание: 

  

 


background image

Часть II. Язык программирования С++ 

242 

 

локального типа; 

 

типа без связывания (linkage); 

 

анонимного типа. 

Параметр-тип  представляет  собой  тип  данных  в  определении 
функции. 
Например,  в  листинге  18.1  определен  шаблон  функции 

xchange

обменивающей  значения  переменных.  Тип  переменных  опреде-
ляется параметром 

T

 шаблона. 

Листинг 18.1. Определение шаблона функции 

template <class T> inline void xchange(T &a, T &b) 

  T tmp = а; 
  a = b; 
  b = tmp; 

Параметр-тип  шаблона  можно  использовать  для  задания  типа 
возвращаемого функцией значения. 
Например, в листинге 18.2 определен шаблон функции 

min

, нахо-

дящей минимальный элемент массива. При этом тип массива яв-
ляется параметром 

T

 шаблона. 

Листинг 18.2. Параметр шаблона как тип возвращаемого функцией 
значения 

template <class T> T min(T *a, const int size) 

  T m = a[0]; 
  for (int i = 1; i < size; ++i) 
    if (a[i] < m) 
      m = a[i]; 
  return m; 

Параметр-не-тип  (non-type  template  parameter)  шаблона  функции 
объявляется  как  переменная,  которая  используется  в  определе- 


background image

Глава 18. Шаблоны функций 

243 

нии  функции.  Эта  переменная  может  иметь  один  из  следующих 
типов: 

 

целочисленный тип; 

 

тип перечисления; 

 

указатель на объект, функцию или член класса; 

 

ссылка на объект или функцию. 

Параметр-не-тип может быть определен с квалификаторами 

const

 

и 

volatile

Например,  в  листинге  18.3  определен  шаблон  функции 

min

  для 

нахождения  минимального  элемента  массива,  параметр 

size

  ко-

торого не является типом и определяет размерность массива. 

Листинг 18.3. Определение шаблона функции с параметром,  
который не является типом 

template <int size, class T> T min(T *a) 

  const int n = size; 
  T m = a[0]; 
  for (int i = 1; i < n; ++i) 
    if (a[i] < m) 
      m = a[i]; 
  return m; 

Параметром шаблона функции может быть также шаблон класса. 
Использование шаблонов класса в качестве параметров шаблонов 
функций рассмотрено в 

разд. 19.10

18.2. Конкретизация шаблона  

функции 

Процесс создания из шаблона функции определения конкретной 
функции  называется 

конкретизацией

  или 

инстанциированием

 

(instantiation) шаблона. Определения функции, созданные из шаб-
лона  функции,  называются 

специализациями  шаблона  функции

 


background image

Часть II. Язык программирования С++ 

244 

или 

шаблонными  функциями

.  Конкретизация  шаблона  функции 

может быть явной или неявной. 
При  явной  конкретизации  шаблона  функции  после  имени  функ-
ции нужно сначала указать параметры шаблона в угловых скоб-
ках, а затем — параметры функции в круглых скобках. 
Например, следующий вызов функции 

xchange

 инициирует явную 

конкретизацию этой функции: 

  int n = 10, m = 20; 
  xchange<int>(n, m); 

В этом случае компилятор создаст из шаблона функции опреде-
ление следующей функции: 

  inline void xchange<int>(int &a, int &b) 
  { 
    int tmp = a; 
    a = b; 
    b = tmp; 
  } 

Отметим, что после имени шаблонной функции в угловых скоб-
ках указаны аргументы шаблона функции, что позволяет компи-
лятору отличать шаблонные функции от обычных нешаблонных 
функций. 
Шаблон функции конкретизируется неявно, если опущен хотя бы 
один его параметр. Это может быть как при вызове функции, так 
и  при  определении  адреса  функции.  Если  какой-то  параметр 
шаблона  опущен,  то  также  должны  быть  опущены  и  все  после-
дующие параметры. 
Например, следующий вызов функции 

xchange

 инициирует неяв-

ную конкретизацию шаблона этой функции: 

double a = 1.5, b = 2.5; 
  xchange(a, b); 

В листинге 18.4 приведены примеры явной и неявной конкрети-
зации  шаблона  функции 

xchange

.  Предполагается,  что  определе-


background image

Глава 18. Шаблоны функций 

245 

ние  шаблона  функции 

xchange

  хранится  в  заголовочном  файле 

xchange.h, текст которого был приведен в листинге 18.1. 

Листинг 18.4. Конкретизация шаблона функции 

#include "xchange.h" 
#include <iostream> 
using namespace std; 
int main() 

  int n = 10, m = 20; 
  xchange<int>(n, m);  // явная конкретизация шаблона функции 
  cout << n << ' ' << m << endl;  // печатает 20 10 
  double a = 1.5, b = 2.5; 
  xchange(a, b);       // неявная конкретизация функции 
  cout << a << ' ' << b << endl;  // печатает 2.5 1.5 
  return 0; 

Когда  компилятор  встречает  обращение  к  функции,  то  адрес 
нужной функции ищется в следующей последовательности: 

 

выполняется  поиск  нешаблонной  функции  с  точным  соответ-
ствием параметров; 

 

выполняется  поиск  шаблонной  функции  с  точным  соответст-
вием параметров; 

 

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

Отсюда  видно,  что  преобразования  типов  аргументов  шаблона 
при  неявной  конкретизации  шаблона  не  используются.  Однако 
при  явной  конкретизации  шаблона  производный  класс  может 
быть приведен к базовому классу. 
В листинге 18.5 приведен пример явной конкретизации шаблона 
функции с приведением производного класса к базовому классу. 
Предполагается, что определение шаблона функции 

xchange

 хра-

нится  в  заголовочном  файле  xchange.h,  текст  которого  был  при-
веден в листинге 18.1. 


Смотрите также файлы