Как правильно реализовать пользовательские итераторы с наследованиемC++

Программы на C++. Форум разработчиков
Anonymous
Как правильно реализовать пользовательские итераторы с наследованием

Сообщение Anonymous »

Я заново изобрел вектор STL для практики и понимания. Естественно, мне также пришлось реализовать систему итераторов. Для возможности повторного использования я хотел реализовать все категории итераторов с наследованием (например: class random_access_iterator : public bidirect_iterator).
Теперь я столкнулся с огромной проблемой. проблема. Рассмотрим следующий фрагмент:

Код: Выделить всё

custom_vector::iterator it_start = container.begin(), it_end = container.end();
custom_vector other_container(it_start, --(--it_end));
Поскольку оператор декремента имеет двунаправленный итератор категории, я также реализовал его там.

Код: Выделить всё

template 
class bidirectional_iterator : public forward_iterator
{
// ...
public:
/* Decrement Operators */
bidirectional_iterator &operator--() { /* code */ }
bidirectional_iterator operator--(int) { /* code */ }
// ...
}
Учитывая это, следующий код не будет работать, поскольку первый аргумент будет иметь тип random_access_iterator, а второй аргумент будет иметь тип bidirected_iterator. Поскольку операторы декремента возвращают двунаправленный_итератор.

Код: Выделить всё

custom_vector other_container(it_start, --(--it_end));
Поскольку не имеет смысла иметь конструктор с двумя разными типами итераторов (и поскольку вектор STL также не имеет такого конструктора), я не буду реализовывать такой конструктор, что приводит к ошибке компиляции.

Код: Выделить всё

error: no matching constructor for initialization of 'custom_vector'
custom_vector other_container(it_start, --(--it_end));
^               ~~~~~~~~~~~~~~~~~~~~~~
candidate constructor not viable: no known conversion from 'custom_vector::iterator' (aka 'random_access_iterator') to 'custom_vector::size_type' (aka 'unsigned long') for 1st argument
explicit custom_vector(size_type n, const value_type &val = value_type(), const allocator_type &alloc = allocator_type()) : _capacity(n), _alloc(alloc)
^
note: candidate template ignored: deduced conflicting types for parameter 'InputIterator' ('random_access_iterator' vs. 'bidirectional_iterator')
custom_vector(InputIterator first, InputIterator last, const allocator_type &alloc = allocator_type(),
^
note: candidate constructor not viable: allows at most single argument 'alloc', but 2 arguments were provided
explicit custom_vector(const allocator_type &alloc = allocator_type()) : _capacity(), _alloc(alloc), _content() {}
^
note: candidate constructor not viable: requires single argument 'x', but 2 arguments were provided
custom_vector(const custom_vector &x) : _capacity(x.capacity()), _alloc(x.get_allocator()), _content()
^
1 error generated.
  • Правильна ли моя реализация Iterator с наследованием? Имеет ли смысл придерживаться этой реализации или было бы лучше просто реализовать для каждого контейнера определенный итератор?
  • Есть ли способ реализовать «конвертер итератора», который автоматически преобразует пример моего двунаправленного_итератора в случайный_итератор_доступа, когда это необходимо?


Подробнее здесь: https://stackoverflow.com/questions/721 ... nheritance

Вернуться в «C++»