Алгоритмы STL, принимающие весь контейнер вместо.begin(), end() в качестве аргумента?

Автономные алгоритмы STL (например, std::count_if) возьми пару итераторов. Во всех случаях, когда я их использую (и во всех примерах, которые я видел в Интернете!), Я печатаю

std::count_if(myContainer.begin(),myContainer.end(), /* ... */ );

Есть ли причина, по которой сокращенные шаблоны стиля

std::count_if(myContainer, /* ... */ );

не предусмотрены, учитывая, что больше всего операций выполняется над всем контейнером? Я только что пропустил это? Различен ли ответ для C++11 и C++03?

4 ответа

Решение

Есть хороший пост в блоге Херба Саттера, в котором обсуждается этот вопрос. Суть в том, что добавление контейнерных перегрузок для алгоритмов может создать неоднозначности, если перегрузка для этого алгоритма с таким же количеством параметров шаблона уже существует. Концепции были предназначены для решения этой проблемы.

Принцип и гибкость STL в основном из-за работы на итераторах, а не на контейнерах. Это не большая проблема, вы можете повторно использовать трюк, который я использую с ранних лет:

#define FULL_RANGE(c) (c).begin(), (c).end()

std::copy(FULL_RANGE(c), std::ostream_iterator<c::value_type>(cout, "\n")); 

Одной из причин может быть предоставление гибкости для диапазона итераторов. Вам, возможно, не понадобится когда-нибудь перебирать все элементы:

<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(), /* ... */ );
}

Просто потому, что алгоритмы STL связаны / разговаривают с контейнером, используя итераторы.

Другие вопросы по тегам