Алгоритмы STL, принимающие весь контейнер, а не .begin(), end() как arg?
Автономные алгоритмы STL (например, std::count_if
) принимают пару итераторов. Во всех случаях, когда я использую эти (и во всех примерах, которые я видел в Интернете!), Я нахожу себя набрав
std::count_if(myContainer.begin(),myContainer.end(), /* ... */ );
Есть ли причина, почему сокращенные шаблоны стиля
std::count_if(myContainer, /* ... */ );
не предоставляются, учитывая, что больше, чем не операция, выполняемая на всем контейнере? Я просто забыл об этом? Является ли ответ другим для С++ 11 и С++ 03?
Ответы
Ответ 1
Существует хороший блог-пост Херба Саттера, который обсуждает этот вопрос. Суть в том, что добавление перегрузок на основе контейнеров для алгоритмов может создавать неоднозначности, если перегрузка для этого алгоритма с тем же числом параметров шаблона уже существует. Концепции были предназначены для устранения этой проблемы.
Ответ 2
Одной из причин может быть предоставление гибкости для диапазона итераторов. Возможно, вам не потребуется итерации через все элементы:
<iterator> it = myContainer.begin();
it++; // do something
it++; // do something
...
std::count_if(it, myContainer.end(), /* ... */ );
Кроме того, вы всегда можете иметь оболочку, которая делает это для вас:
template<typename T>
... count_if (T myContainer, ...)
{
std::count_if(myContainer.begin(), myContainer.end(), /* ... */ );
}
Ответ 3
Принцип STL и гибкость в основном обусловлены работой на итераторах вместо контейнеров. Это не большая проблема, вы можете повторно использовать трюк, который я использую с ранних лет C:
#define FULL_RANGE(c) (c).begin(), (c).end()
std::copy(FULL_RANGE(c), std::ostream_iterator<c::value_type>(cout, "\n"));
Ответ 4
Просто потому, что алгоритмы STL связаны/взаимодействуют с контейнером с помощью итераторов.