Алгоритмы 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 связаны/взаимодействуют с контейнером с помощью итераторов.