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