В рамках этого примера мы разместили простой алгоритм счета в интерфейсе однонаправленного итератора. Реализация итератора и диапазона данных зачастую включает в себя написание минимального объема стереотипного кода, что, с одной стороны, может слегка раздражать. С другой стороны, взглянув на цикл, который использует num_range
Обеспечиваем совместимость собственных итераторов с категориями итераторов STL
Какую бы структуру данных вы ни создали, для эффективного
Проблема заключается в том, что многие алгоритмы STL пытаются больше узнать об итераторах, с которыми должны работать. Разные
memcpy
. Если мы копируем данные из списка или в него, то такой вызов сделать Как это делается
В этом примере мы реализуем примитивный итератор, считающий числа, и используем его вместе с алгоритмом STL, с которым он изначально не будет компилироваться. Затем сделаем все, чтобы итератор стал совместим с STL.
1. Сначала, как обычно, включим некоторые заголовочные файлы:
#include
#include
2. Далее реализуем примитивный итератор для подсчета чисел, как было показано в предыдущем разделе. При переборе он генерирует обычные увеличивающиеся целые числа. Диапазон данных num_range
class num_iterator
{
int i;
public:
explicit num_iterator(int position = 0) : i{position} {}
int operator*() const { return i; }
num_iterator& operator++() {
++i;
return *this;
}
bool operator!=(const num_iterator &other) const {
return i != other.i;
}
bool operator==(const num_iterator &other) const {
return !(*this != other);
}
};
class num_range {
int a;
int b;
public:
num_range(int from, int to)
: a{from}, b{to}
{}
num_iterator begin() const { return num_iterator{a}; }
num_iterator end() const { return num_iterator{b}; }
};
3. Чтобы избавиться от префикса пространства имен std::
std
:using namespace std;
4. Теперь просто создадим диапазон данных, содержащий числа от 100
109
. Обратите внимание: конечный итератор стоит в позиции 110
. Это значит, что 110
— 100
и заканчивается значением 109
):int main()
{
num_range r {100, 110};
5. Теперь воспользуемся им для std::minmax_element
std::pair
с двумя членами: итератором, указывающим на минимальное значение, и другим итератором, указывающим на максимальное значение. В нашем примере этими значениями будут 100
и 109
, поскольку именно с их помощью мы создавали диапазон данных: auto [min_it, max_it] (minmax_element(begin(r), end(r)));
cout << *min_it << " - " << *max_it << '\n';
}