Не в случае remove_if
, так как семантика различна. std::remove_if
на самом деле ничего не удаляет из контейнера, в то время как list::remove_if
делает, так что вы определенно не хотите, чтобы первое вызывало второе.
Ни вы, ни реализация не могут буквально специализировать универсальные алгоритмы для контейнеров, поскольку алгоритмы являются шаблонами функций, которые принимают итераторы, а сами контейнеры являются шаблонами классов, тип итератора которых зависит от параметра шаблона. Таким образом, чтобы специализировать std::remove_if
в общем случае для list<T>::iterator
, вам потребуется частичная специализация remove_if
, и нет такой вещи, как частичная специализация шаблона функции.
Я не могу вспомнить, разрешено ли реализациям перегружать алгоритмы для определенных типов итераторов, но даже если не "официальный" алгоритм, может вызывать функцию, которая может быть перегружена, или он может использовать класс, который может быть частично специализированным. К сожалению, ни один из этих методов не поможет вам, если вы написали свой собственный контейнер и нашли способ сделать стандартный алгоритм особенно эффективным для него.
Предположим, например, что у вас есть контейнер с итератором с произвольным доступом, но где у вас есть особенно эффективный метод сортировки, который работает со стандартным порядком: сортировка по сегментам, возможно. Тогда вы можете подумать о том, чтобы поместить свободную функцию template <typename T> void sort(MyContainer<T>::iterator first, MyContainer<T>::iterator last)
в то же пространство имен, что и класс, и позволить людям вызывать ее с помощью using std::sort; sort(it1, it2);
вместо std::sort(it1, it2);
. Проблема заключается в том, что если они делают это в общем коде, они рискуют, чтобы кто-то еще, пишущий какой-либо другой тип контейнера, имел функцию sort
, которая даже не сортирует диапазон (английское слово "sort" имеет более одного значения , в конце концов). Таким образом, в общем случае вы не можете в общем случае сортировать диапазон итераторов таким образом, чтобы получать информацию об эффективности для пользовательских контейнеров.
Когда разница в коде зависит только от категории итератора (например, std::distance
, который быстр для итераторов с произвольным доступом и медленный в противном случае), это делается с помощью так называемой «отправки тега итератора», и это Наиболее распространенный случай, когда существует явная разница в эффективности между различными контейнерами.
Если есть какие-либо оставшиеся случаи, которые применяются к стандартным контейнерам (исключая случаи, когда результат отличается или если эффективность требует только определенной категории итераторов), давайте их рассмотрим.