Бьерн Страуструп.
Язык программирования С++
223
контейнерных классов, поскольку для последних первостепенным фактором, определяющим их
эффективность, является возможность размещать их вне свободной памяти. Например, если в
реализации класса string короткие строки размещаются в стеке, это дает существенный выигрыш для
программы, поскольку в большинстве задач практически все строки очень короткие. Для реализации
таких типов как раз и может пригодиться шаблон buffer.
Каждый параметр шаблона типа для функции должен влиять на тип функции, и это влияние
выражается в том, что он участвует по крайней мере в одном из типов формальных параметров
функций, создаваемых по шаблону. Это нужно для того, чтобы функции можно было выбирать и
создавать, основываясь только на их параметрах:
template
void f1(T);
//
нормально
template void f2(T*);
//
нормально
template T f3(int);
//
ошибка
template void f4(int[][i]);
//
ошибка
template void f5(int = i);
//
ошибка
template void f6(T);
//
ошибка
template void f7(const T&, complex);
//
нормально
template void f8(Vector< List >);
//
нормально
Здесь все ошибки вызваны тем, что параметр-тип шаблона никак не влияет на формальные параметры
функций.
Подобного ограничения нет в шаблонах типа для классов. Дело в том, что параметр для такого
шаблона нужно указывать всякий раз, когда описывается объект шаблонного класса. С другой стороны,
для шаблонных классов возникает вопрос: когда два созданных по шаблону типа можно считать
одинаковыми? Два имени шаблонного класса обозначают один и тот же класс, если совпадают имена
их шаблонов, а используемые в этих именах параметры имеют одинаковые значения (с учетом
возможных определений typedef, вычисления выражений-констант и т.д.). Вернемся к шаблону buffer:
template
class buffer {
T
v[sz];
//
...
};
void f()
{
buffer
buf1;
buffer
buf2;
buffer
buf3;
buffer
buf4;
buf1 = buf2; // ошибка: несоответствие типов
buf1 = buf3; // нормально
buf1 = buf4; // ошибка: несоответствие типов
//
...
}
Если в шаблоне типа для класса используются параметры, задающие не типы, возможно появление
конструкций, выглядящих двусмысленно:
template
class X { /* ... */ };
void f(int a, int b)
{
X < a > b>;
// Как это понимать: X b и потом
// недопустимая лексема, или X< (a>b) >; ?
}
Этот пример синтаксически ошибочен, поскольку первая угловая скобка > завершает параметр
шаблона. В маловероятном случае, когда вам понадобится параметр шаблона, являющийся
Бьерн Страуструп.
Язык программирования С++
224
выражением "больше чем", используйте скобки: X< (a>b)>.
Достарыңызбен бөлісу: