Бьерн Страуструп.
Язык программирования С++
219
}
Отметим, что включение в шаблон класса Comparator как параметра гарантирует, что функция lessthan
будет реализовываться подстановкой. В
частности, это полезно, если в шаблонной функции
используется несколько функций, а не одна операция сравнения, и особенно это полезно, когда эти
функции зависят от хранящихся в том же объекте данных.
8.4.4 Неявная передача операций
В примере из предыдущего раздела объекты Comparator на самом деле никак не использовались в
вычислениях. Это просто "искусственные" параметры, нужные для правильного контроля типов.
Введение таких параметров достаточно общий и полезный прием, хотя и не слишком красивый. Однако,
если объект используется только для передачи операции (как и было в нашем случае), т.е. в
вызываемой
функции не используется ни значение, ни адрес объекта, то можно вместо этого
передавать операцию неявно:
template
void sort(Vector& v)
{
unsigned n = v.size();
for (int i=0; ifor (int j=n-1; iif
(Comparator::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& vi,
Vector&
vc,
Vector&
vi2,
Vector&
vs)
{
sort(vi); // sort(Vector&);
sort(vc); // sort(Vector&);
sort(vi2); // sort(Vector&);
sort(vs); // sort(Vector&);
}
Основное преимущество этого варианта, как и двух предыдущих, по сравнению с исходным вариантом
в том, что часть программы, занятая собственно сортировкой, отделена от частей, в которых находятся
такие операции, работающие с элементами, как, например lessthan. Необходимость подобного
разделения растет с ростом программы, и особенный интерес это разделение представляет при
проектировании библиотек. Здесь создатель библиотеки не может знать типы параметров шаблона, а
пользователи не знают (или не хотят знать) специфику используемых в шаблоне алгоритмов. В
частности, если бы в функции sort() использовался более сложный, оптимизированный и рассчитанный
на коммерческое применение алгоритм, пользователь не очень бы стремился написать свою особую
версию для типа char*, как это было сделано в $$8.4.1. Хотя реализация класса Comparator для
специального случая char* тривиальна и может использоваться и в других ситуациях.
Достарыңызбен бөлісу: