Бьерн Страуструп - Язык программирования С++. Главы 8-10 - Неявная передача операций

ОГЛАВЛЕНИЕ


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

В примере из предыдущего раздела объекты 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* тривиальна и может использоваться и в других ситуациях.