Как и обычные функции, шаблоны функций также могут быть перегружены , так что вы можете получить лучшее из обоих миров: алгоритм на основе итератора для больше гибкости и контейнеров для простоты использования.
Таким образом, вы можете использовать перегрузку на основе итератора для обработки поддиапазона контейнера и перегрузку на основе контейнера для обработки всех элементов контейнера.
process(first, last)
Я бы предложил сначала определить шаблон функции process()
, который принимает пару итераторов для последовательности элементов, которые вы хотите обработать:
template<typename Iterator>
void process(Iterator begin, Iterator end) {
for (auto it = begin; it != end; ++it) {
// ...
}
}
Это алгоритм на основе итератора (т. Е. Он принимает пару итераторов) и соответствует тому же подходу, которому следуют алгоритмы STL.
process(container)
Затем я бы определил другой шаблон функции process()
, который перегружает первого. Эта перегрузка принимает контейнер и вызывает основанную на итераторах версию process()
для элементов переданного контейнера:
template<typename Container>
void process(Container const& c) {
process(std::begin(c), std::end(c));
}
Это алгоритм на основе контейнера , так как он принимает контейнер.
Таким образом, вы можете использовать алгоритм на основе контейнера вместо алгоритма на основе итератора:
std::vector<int> vec{1, 2, 3};
std::list<int> lst{1, 2, 3};
std::array<int, 3> arr{1, 2, 3};
int carr[] = {1, 2, 3};
process(vec);
process(lst);
process(arr);
process(carr);
Этот алгоритм отделен от контейнеров для обработки (например, он работает даже с массивами в стиле C, как вы можете видеть), но вы вызываете его непосредственно в контейнере вместо прохождения итераторов.
Вы всегда можете вызвать перегрузку process()
, которая принимает пару итераторов вместо контейнера, если вы не хотите обрабатывать все элементы контейнера, а просто поддиапазон элементов в нем.