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

       

Неявная передача операций


В примере из предыдущего раздела объекты Comparator на самом деле никак не использовались в вычислениях. Это просто "искусственные" параметры, нужные для правильного контроля типов. Введение таких параметров достаточно общий и полезный прием, хотя и не слишком красивый. Однако, если объект используется только для передачи операции (как и было в нашем случае), т.е. в вызываемой функции не используется ни значение, ни адрес объекта, то можно вместо этого передавать операцию неявно:

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 (Comparator<T>::lessthan(v[j],v[j-1])) {

          // меняем местами v[j] и v[j-1]

          T temp = v[j];

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

          v[j-1] = temp;

       }

}

В результате мы приходим к первоначальному варианту использования sort():

void f(Vector<int>& vi,

       Vector<String>& vc,

       Vector<int>& vi2,

       Vector<char*>& vs)

{

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

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

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

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

}

Основное преимущество этого варианта, как и двух предыдущих, по сравнению с исходным вариантом в том, что часть программы, занятая собственно сортировкой, отделена от частей, в которых находятся такие операции, работающие с элементами, как, например lessthan. Необходимость подобного разделения растет с ростом программы, и особенный интерес это разделение представляет при проектировании библиотек. Здесь создатель библиотеки не может знать типы параметров шаблона, а пользователи не знают (или не хотят знать) специфику используемых в шаблоне алгоритмов. В частности, если бы в функции sort() использовался более сложный, оптимизированный и рассчитанный на коммерческое применение алгоритм, пользователь не очень бы стремился написать свою особую версию для типа char*, как это было сделано в $$8.4.1. Хотя реализация класса Comparator для специального случая char* тривиальна и может использоваться и в других ситуациях.



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