Программирование >>  Разработка устойчивых систем 

1 ... 52 53 54 [ 55 ] 56 57 58 ... 196


public: void pushCconst Т& t): И т. д.

Если теперь при объявлении шаблона опустить второй аргумент, то значение N по умолчанию будет равным 100.

Значения по умолчанию можно определить для всех аргументов, но тогда при объявлении экземпляра необходимо использовать пустые угловые скобки. Без них компилятор не поймет, что речь идет о шаблоне класса:

tempiate<c1ass Т = int. size t N - 100> Значения по умолчанию class Stack ( у обоих параметров

Т dataCN]; Фиксированная емкость N

size t count: public:

void pushCconst T& t):

И т. д.

Stacko myStack: To же, что Stack<int,100>

Аргументы по умолчанию широко используются в стандартной библиотеке С++. Например, шаблон класса vector объявляется следующим образом:

template <class Т. class Allocator - allocator<T> > class vector:

Обратите внимание на пробел между правыми угловыми скобками. Без него компилятор интерпретировал бы эти символы ( ) как оператор сдвига.

Объявление показывает, что шаблон vector получает два аргумента: тип хранящихся в нем объектов и тип используемого шаблоном vector распределителя памяти. Если второй аргумент не указан, применяется стандартный шаблон allocator, параметризованный по типу первого параметра шаблона. Данное объявление также показывает, что параметры шаблонов тоже могут указываться в последующих параметрах шаблонов, как параметр Т в нашем примере.

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

: C05:FuncDef.cpp #incl ude <iostream> using namespace std;

tempiate<class T> T sumCT* b. T* e. T init - TO) { whileCb != e)

init += *b++; return init:

int mainO { int a[] = {1.2,3};

cout sumCa. a+sizeof a / sizeof aCO]) endl: 6 } III:-

Третий аргумент sum() определяет начальное значение накапливаемой суммы. Поскольку при вызове он не указан, по умолчанию этот аргумент равен Т(). В слу-



чае типа int и других встроенных типов это приводит к вызову псевдоконструктора и инициализации переменной нулями.

Шаблоны как параметры шаблонов

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

: C05:TempTemp.cpp

Шаблоны как параметры шаблонов

linclude <cstddef>

linclude <iostream>

using namespace std:

tempiate<class T>

class Array { Простой, динамически расширяемый массив

enum (INIT = 10}: Т *data:

size t capacity: size t count: public: ArrayO { count = 0:

data = new T[capacity = INIT]:

-ArrayO ( delete [] data: } void push back(const T& t) ( if(count == capacity) {

Увеличение базового массива

size t newCap = 2*capacity:

T* newData = new T[newCap]:

for (size t i =0: i < count: ++i) newData[i] = data[i]:

delete data:

data = newData:

capacity = newCap:

data[count++] = t:

void pop back() ( if(count > 0) --count:

T* beginО ( return data: }

T* endO ( return data + count: }

tempiate<class T. tempiate<c1ass> class Seq> class Container {

Seq<T> seq: public:

void append(const T& t) ( seq.push back(t):

T* beginO ( return seq.begin(): } T* endO ( return seq.endO: }



int mainO (

Container<int. Аггау> container:

contalner.append(l):

container.append(2):

int* p = contalner.begInO:

whIleCp != container.endO) cout *p++ endl: } III:-

Шаблон класса Array представляет собой тривиальный контейнер для хранения последовательности элементов. Шаблон Container получает два параметра: тип хранящихся в нем объектов и шаблон, предназначенный для хранения данных. Следующая строка в реализации класса Container требует, чтобы мы сообщили компилятору о том, что Seq является шаблоном:

Seq<T> seq:

Если не объявить Seq как шаблон, являющийся параметром шаблона, то компилятор пожалуется, что Seq не является шаблоном, поскольку мы задействуем его в нешаблонном контексте. В функции main() создается специализация Container, использующая шаблон Array для хранения int, так что Seq фактически является синонимом для Array.

Обратите внимание: задавать имя параметра Seq в объявлении Container в данном случае не нужно. Речь идет о строке

tempiate<class Т. tempiate<class> class Seq>

Хотя с таким же успехом можно было написать следующую строку, параметр U нигде не используется:

tempiate<class Т. tempiate<class U> class Seq>

Важно лишь то, что Seq - шаблон класса, получающий один параметр-тип. Можно провести аналогию с пропуском имен неиспользуемых параметров функций, как при перегрузке постфиксного оператора ++:

Т operator++(1nt):

В данном случае тип int передает всю необходимую информацию, и имя переменной не требуется.

В следующей программе используется массив фиксированного размера, в шаблоне которого определен дополнительный параметр, задающий длину массива:

: C05:TempTemp2.cpp

Шаблон как параметр шаблона с несколькими параметрами #1 nclude <cstddef> #1 nclude <1ostream> using namespace std:

tempiate<class T. s1ze t N> class Array ( T data[N]: s1ze t count: public: ArrayО { count = 0; } void push back(const T& t) { 1f(count < N) data[count++] = t:



1 ... 52 53 54 [ 55 ] 56 57 58 ... 196

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