Надо мне было сделать полиморфный итератор, т.е. чистый интерфейс для итератора, т.к. типы которые итерируются — неизвестны на стадии компиляции. Интерфейс примерно такой:
class CBlablaIterator :
public MyBaseIterator
{
protected:
const IterationType* m_IterObject; //Класс, объект которого итерируем по базовому интерфейсу.
IterationTypeContainer::const_iterator m_IterObjectIt; //Итератор на контейнер-мембер внутри итерируемого объекта.
//bool m_asForward; //Нежелательный параметр, см. далее.
//...
};
Здравствуйте, Vain, Вы писали:
V>Надо мне было сделать полиморфный итератор, т.е. чистый интерфейс для итератора, т.к. типы которые итерируются — неизвестны на стадии компиляции. Интерфейс примерно такой: V>Можно ли как-нибудь обойтись без этого m_asForward? Почему итераторы для двунаправленных контейнеров — однонаправленные?
подождите. Вы хотите начинать итерирование как с конца, так и сначала, и осуществлять его в обоих направлениях, так?
для того, чтобы начать, нужно знать, откуда, и эта информация у метода start есть.
для того, чтобы совершить итерацию, нужно знать, в какую сторону, и эта информация у метода step тоже есть.
теперь нужно выяснить, какова логика метода done.
варианта здесь я вижу 2 —
1. done() == true при достижении последнего элемента при старте с первого(и наоборот, первого при старте с последнего)
2. done() == true при невозможности итерироваться в сторону, в которую была совершена последняя итерация ( как это сделано у Вас, если раскомментировать обращения к m_asForward, обратите внимание, если на самом деле нужно другое )
и в обоих случаях, нужно знать, а что же является последним элементом для текущего процесса итерации.
на мой взгляд, простейшим вариантом как раз и будет флаг направления, можно конечно и итератор на последний элемент хранить, либо даже функтор, возвращающий итератор на последний элемент.
и иметь две НЕЗАВИСИМЫЕ реализации для прямого итератора и для обратного.
Можно, даже, легко, довольно, сделать это всё шаблонным.
Ну, типа как-то так:
ну и не заморачиваться особо. Правда при этом могут быть проблемы с владением.
То есть, если у тебя от чего-то есть проблемы с размножением объектов-итераторов, то можно воспользоваться следующим трюком
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Vain, Вы писали:
V>Надо мне было сделать полиморфный итератор, т.е. чистый интерфейс для итератора, т.к. типы которые итерируются — неизвестны на стадии компиляции. Интерфейс примерно такой:
Почитай здесь(все, 1-15), Александреску уже все давно придумал
Здравствуйте, Vain, Вы писали:
V>Надо мне было сделать полиморфный итератор, т.е. чистый интерфейс для итератора, т.к. типы которые итерируются — неизвестны на стадии компиляции. Интерфейс примерно такой: V>
чёто слишком сложно, создайте базовый класс с чисто виртуальными функциями которые необходимы для данного типа итератора, а дальше в обёртке над boost::iterator_facade просто их вызывайте, например для самого простого последовательного итератора будет нечто такое: