5. При инкрементировании итератор (++it
fibit& operator++() {
const size_t old_b {b};
b += a;
a = old_b;
++i;
return *this;
}
6. При использовании в цикле инкрементированный итератор сравнивается с конечным итератором, для чего следует реализовать оператор !=
1000000
, поскольку не нужно выполнять трудоемкие вычисления этого довольно большого числа Фибоначчи bool operator!=(const fibit &o) const { return i != o.i; }
};
7. Чтобы иметь возможность использовать итератор Фибоначчи в основанном на диапазоне цикле for
fib_range
. Его конструктор будет принимать один параметр, который скажет, насколько далеко нужно проитерировать по диапазону данных:class fib_range
{
size_t end_n;
public:
fib_range(size_t end_n_)
: end_n{end_n_}
{}
8. Функции begin
end
возвращают итераторы, которые указывают на позиции F(0)
и F(end_n)
: fibit begin() const { return fibit{}; }
fibit end() const { return fibit{end_n}; }
};
9. О’кей, теперь забудем о реализации стереотипного кода, связанного с итераторами. Теперь у нас есть вспомогательный класс, который аккуратно скрывает детали реализации! Выведем на экран первые десять чисел Фибоначчи.
int main()
{
for (size_t i : fib_range(10)) {
std::cout << i << ", ";
}
std::cout << '\n';
}
10. Компиляция и запуск программы дадут следующий результат:
1, 1, 2, 3, 5, 8, 13, 21, 34, 55,
Дополнительная информация
Использование этого итератора совместно с библиотекой STL предполагает, что он должен поддерживать класс std::iterator_traits
Чтобы не усложнять пример, мы ничего с ним не сделали, хотя могли опубликовать итератор Фибоначчи в виде библиотеки. В таком случае станет понятно, что у нее есть один недостаток: экземпляр fibit
□ Сделать конструктор fibit(size_t i_)
fib_range
является дружественным для класса fibit
. Таким образом, пользователи могут применять его только корректным способом.□ Задействовать особые символы, чтобы помешать пользователям разыменовать конечный итератор. Взгляните на пример, в котором мы делаем именно это:
Перебор в обратную сторону с применением обратных адаптеров для итераторов
Иногда может быть полезно итерировать по диапазону данных не вперед, а
for
, а также все алгоритмы STL обычно итерируют по диапазонам данных, инкрементируя итераторы, однако перебор (итерирование) в обратную сторону требует выполнения операции Библиотека STL предоставляет полезный
Как это делается
В этом примере мы будем разными способами применять обратные итераторы, чтобы показать варианты их использования.
1. Как обычно, включим некоторые заголовочные файлы:
#include
#include
#include
2. Далее объявляем об использовании пространства имен std