Программирование >>  Расширенная версия языка c++ 

1 ... 104 105 106 [ 107 ] 108 109 110 ... 227


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

Примеры

1. В следующей программе создается родовая кция, которая меняет местами значения двух переменных, передаваемых ей в качестве параметров. Поскольку в своей основе процесс обмена двух значений не зависит от типа переменных, этот процесс удачно реализуется с помощью родовой функции.

Пример родовой функции или шаблона ttinclude <iostream>

using namespace std; , , , .,

Это функция-шаблон

template <class X> void swapargs (X &a, X &b)

X temp;

temp

b = temp;

int i = 10, j = 20;

float X = 10.1, у = 23.3;

cou Исходнхе значения i, j равн! cou Исходные значения x, у равные x

swapargs (i, j);

swapargs (x, y) ;

обмен целых

обмен действительных

cou << Новые значение 1, j равные cou Новые значения x, у равные

return О;

у endl;

j endl; endl;

1 -

Ключевое слов mplate используется для определения родовой функции. Строка:

template <clas: - voi з {X Sa, X &b)

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



328 ; Самоучитель C++

словом template функция swapargs() объявляется с именем X в качестве типа данных обмениваемых значений. В функции mainO функция swapargs() вызывается с двумя разными типами данных: целыми и действительными. Поскольку функции args() - это родовая кция, компилятор автоматически создает две ее версии: одну - для обмена целых значений, другую для обмена действительных значений. Теперь попытайтесь скомпилировать программу.

Имеются и другие термины, которые можно встретить при описании шаблонов в литературе по C++. Во-первых, родовая функция (то есть функция, в определении которой имеется ключевое слово template) также называется функция-шаблон (template junction). Когда компилятор создает конкретную версию этой функции, говорят, что он создал порожденную функцию (generated function). Процесс генерации порожденной функции называют созданием экземпляра (instantiating) функции. Другими словами, порожденная функция - это конкретный экземпляр функции-шаблона.

2. Ключевое слово template в определении родовой функции не обязательно

должно быть в той же строке, что и имя функции. Например, ниже приведен еще один вполне обычный формат определения функции swapargs():

template <class X>

void swapargs (X ia, X ub)

X temp;

temp = a; a = b;

b = temp;

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

Этот фрагмент компилироваться не будет template <class X>

int i; это неправильно

void swapargs (X &a, X £b)

X temp;

temp = аг а = b;

b = temp; , r , . .

Как указано в комментариях, инструкция с ключевым словом template должна находиться сразу перед определением функции.



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

3. Как уже упоминалось, для задания родового типа данных в определении шаблона вместо ключевого слова class можно указывать ключевое слово typename. Например, ниже приведено еще одно объявление функции swapargs О:

Использование ключевого слова typename

template ename X> voi s (X &a, X sb)

{ . ., .

X temp;

temp = a; a = b;

b = temp; .

Ключевое слово typename можно также указывать для задания неизвестного типа данных внутри шаблона, но такое его использование выходит за рамки

данной книги,

4. С помощью инструкции Opiate можно определить более одного родового типа данных, отделяя их друг от друга запятыми. Например, в данной программе создается родовая функция, в которой имеются два родовых типа данных:

linclude <iostreain> : .

using namespace std;

template <class typel, class type2>

void myfunc (typel x, type2 y)

cou< < у endl;

myfunc(10, hi ) ; myfunc (0.23, lOL); return 0;

В данном примере при генерации конкретных экземпляров функции myfuncO, фиктивные имена типов typel и type2 заменяются компилятором на типы данных int и char* или double и long соответственно.



1 ... 104 105 106 [ 107 ] 108 109 110 ... 227

© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика