vector
// указателями auto_ptr на Widget. // Помните, что этот фрагмент // не должен компилироваться!
sort(widgets.begin(),widgets.end(), // Отсортировать вектор
widgetAPCompare);
Пока все выглядит вполне разумно, да и с концептуальной точки зрения все
Оказывается, реализация sort часто строится на некой разновидности алгоритма быстрой сортировки. Работа этого алгоритма строится на том, что некоторый элемент контейнера выбирается в качестве «опорного», после чего производится рекурсивная сортировка по значениям, большим и меньшим либо равным значению опорного элемента. Реализация такого алгоритма в sort может выглядеть примерно так:
template
class Compare>// прямо из Стандарта
void sort(RandomAccessIterator first,
RandomAccessIterator last,
Compare comp)
{
// typedef описывается ниже
typedef typename iterator_traits
ElementType;
RandomAccessIterator i;
...// Присвоить i указатель на опорный элемент
ElementType pivotValue(*i); // Скопировать опорный элемент в локальную
...// временную переменную; см. далее комментарий.
// Остальная сортировка
}
Если вы не привыкли читать исходные тексты STL, этот фрагмент выглядит жутковато, но в действительности в нем нет ничего страшного. Нетривиально здесь выглядит только запись iterator_traits
но это всего лишь принятое в STL обозначение типа объекта, на который указывают итераторы, переданные sort. Перед ссылкой iterator_traits
должен стоять префикс typename, поскольку это имя типа, зависящее от параметра шаблона (в данном случае RandomAccessIterator
), — дополнительная информация приведена на с. 20.
Проблемы возникают из-за следующей команды, которая копирует элемент из сортируемого интервала в локальный временный объект:
ElementType pivotValue(*i);
В данном случае элементом является auto_ptr
Впрочем, это вовсе не исключает возможности создания контейнеров умных указателей. Контейнеры умных указателей вполне допустимы. В совете 50 описано, где найти умные указатели, хорошо работающие в контейнерах STL, просто auto_ptr не относится к их числу.
Совет 9. Тщательно выбирайте операцию удаления
Допустим, у нас имеется стандартный контейнер STL с, содержащий числа типа int: