Язык программирования C++ от Страуструпа

Простой шаблон типа для глобальной функции


Начнем с простейшего шаблона для sort():

template<class T> void sort(Vector<T>&);

void f(Vector<int>& vi,

       Vector<String>& vc,

       Vector<int>& vi2,

       Vector<char*>& vs)

{

  sort(vi);                        // sort(Vector<int>& v);

  sort(vc);                        // sort(Vector<String>& v);

  sort(vi2);                       // sort(Vector<int>& v);

  sort(vs);                        // sort(Vector<char*>& v);

}

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



template<class T> void sort(Vector<T>& v)

/*

  Сортировка элементов в порядке возрастания

  Используется сортировка по методу пузырька

*/

{

unsigned n = v.size();

for (int i=0; i<n-1; i++)

  for (int j=n-1; i<j; j--)

     if (v[j] < v[j-1]) {  // меняем местами v[j] и v[j-1]

       T temp = v[j];

       v[j] = v[j-1];

       v[j-1] = temp;

     }

}

Советуем сравнить это определение с функцией сортировки с тем же алгоритмом из $$4.6.9. Существенное отличие этого варианта в том, что вся необходимая информация передается в единственном параметре v. Поскольку тип сортируемых элементов известен (из типа фактического параметра, можно непосредственно сравнивать элементы, а не передавать указатель на производящую сравнение функцию. Кроме того, нет нужды возиться с операцией sizeof. Такое решение кажется более красивым и к тому же оно более эффективно, чем обычное. Все же оно сталкивается с трудностью. Для некоторых типов операция < не определена, а для других, например char*, ее определение противоречит тому, что требуется в приведенном определении шаблонной функции. (Действительно, нам нужно сравнивать не указатели на строки, а сами строки). В первом случае попытка создать вариант sort() для таких типов закончится неудачей (на что и следует надеяться) , а во втором появиться функция, производящая неожиданный результат.



Содержание раздела