Напомним, что определения пространства имен не обязательно непрерывны. Мы можем повторно открыть пространство имен cplusplus_primer для добавления специализации:
// ---- user.C ----
#include primer.h
#include "user.h"
namespace cplusplus_primer {
// специализация для cplusplus_primer::min()
template SmallInt minsmallInt( SmallInt* array, int size )
{ /* ... */ }
}
SmallInt asi[4];
int main() {
// задать значения элементов массива asi с помощью функции-члена set()
using cplusplus_primer::min; // using-объявление
int size = sizeof(asi) / sizeof(SmallInt);
// конкретизируется min(SmallInt*,int)
min( asi[0], size );
}
Можно определить специализацию так, как мы определяем любой другой член пространства имен вне определения самого пространства: квалифицировав имя члена именем объемлющего пространства.
// ---- user.C ----
#include primer.h
#include "user.h"
// специализация для cplusplus_primer::min()
// имя специализации квалифицируется
namespace {
template SmallInt cplusplus_primer::
minsmallInt( SmallInt* array, int size )
{ /* ... */ }
// ...
Если вы, пользуясь библиотекой, содержащей определения шаблонов, захотите написать их специализации, то должны будете удостовериться, что их определения помещены в то же пространство имен, что и определения исходных шаблонов.
Поместим содержимое заголовочного файла exercise.h из упражнения 10.14 в пространство имен cplusplus_primer. Как надо изменить функцию main(), чтобы она могла конкретизировать шаблон max(), находящийся в cplusplus_primer?
Снова обращаясь к упражнению 10.14, предположим, что содержимое заголовочного файла exercise.h помещено в пространство имен cplusplus_primer. Допустим, мы хотим специализировать шаблон функции max() для массивов объектов класса LongDouble. Нужно, чтобы специализация шаблона использовала функцию compareGreater() для сравнения двух объектов класса LongDouble, объявленную как:
// функция сравнения объектов класса LongDouble
// возвращает true, если parm1 больше parm2
bool compareGreater( const LongDouble parm1,
const LongDouble parm2 );
Определение класса LongDouble выглядит следующим образом:
class LongDouble {
public:
LongDouble(double dval) : value(ival) {}
friend bool compareGreater( const LongDouble ,
const LongDouble );
private:
double value;
};
Напишите определение функции compareGreater() и специализацию max(), в которой эта функция используется. Напишите также функцию main(), которая задает элементы массива ad, а затем вызывает специализацию max(), доставляющую его максимальный элемент. Значения, которыми инициализируется массив ad, должны быть получены чтением из стандартного ввода cin.
10.11. Пример шаблона функции
В этом разделе приводится пример, показывающий, как можно определять и использовать шаблоны функций. Здесь определяется шаблон sort(), который затем применяется для сортировки элементов массива. Сам массив представлен шаблоном класса Array (см. раздел 2.5). Таким образом, шаблоном sort() можно пользоваться для сортировки массивов элементов любого типа.
В главе 6 мы видели, что в стандартной библиотеке C++ определен контейнерный тип vector, который ведет себя во многом аналогично типу Array. В главе 12 рассматриваются обобщенные алгоритмы, способные манипулировать контейнерами, описанными в главе 6. Один из таких алгоритмов, sort(), служит для сортировки содержимого вектора. В этом разделе мы определим собственный “обобщенный алгоритм sort()” для манипулирования классом Array, упрощенной версии алгоритма из стандартной библиотеки C++.
Шаблон функции sort() для шаблона класса Array определен следующим образом:
template class elemType
void sort( ArrayelemType array, int low, int high ) {
if ( low high ) {
int lo = low;
int hi = high + 1;
elemType elem = array[lo];
for (;;) {
while ( min( array[++lo], elem ) != elem lo high ) ;
while ( min( array[--hi], elem ) == elem hi low ) ;
if (lo hi)
swap( array, lo, hi );
else break;
}
swap( array, low, hi );
sort( array, low, hi-1 );
sort( array, hi+1, high );
}
}
В sort() используются две вспомогательные функции: min() и swap(). Обе они должны определяться как шаблоны, чтобы иметь возможность обрабатывать любые типы фактических аргументов, с которыми может быть конкретизирован шаблон sort(). min() определена как шаблон функции для поиска минимального из двух значений любого типа: