В общем случае, я не думаю, что это возможно, по крайней мере, не чисто.
По крайней мере, как это обычно определяется, итератор рассчитывает работать с однородной коллекцией.То есть, итератор обычно определяется примерно так:
template <class Element>
class iterator // ...
... поэтому конкретный итератор может работать только с элементами одного определенного типа.Максимум, что вы можете сделать для работы с различными типами, - это создать итератор (указатель / ссылку на) базового класса и позволить ему иметь дело с объектами производных классов.
В отличие от этого, довольно просто написатьпосетитель, подобный этому:
class MyVisitor {
public:
void VisitOneType(OneType const *element);
void VisitAnotherType(AnotherType const *element);
};
Он может посещать узлы либо OneType
, либо AnotherType
, даже если они совершенно не связаны.По сути, у вас есть одна Visit
функция-член в вашем классе Visitor для каждого различного типа class , который он сможет посещать.
Итератор с несколько иной точки зренияв основном специализированная форма посетителя, которая работает только для одного типа объекта.Вы обмениваетесь немного больше контроля над шаблоном посещения в обмен на потерю способности посещать несвязанные типы объектов.
Если вам нужно иметь дело только с одним типом (хотя этот тип может быть базовым классом, ипосещаемые объекты имеют различные производные типы), тогда очевидным методом будет создание класса «bridge», который посещает объекты (Tree
узлов, в вашем примере), а когда вызывается его visit
, он просто копируетадрес узла, который он посещает, в некоторую коллекцию, которая поддерживает итераторы:
template <class T>
class Bridge {
std::vector<T *> nodes;
public:
virtual void visit(T *n) {
nodes.push_back(n);
}
typedef std::vector<T *>::iterator iterator;
iterator begin() { return nodes.begin(); }
iterator end() { return nodes.end(); }
};
Использование этого будет двухэтапным процессом: сначала посетите узлы, как это обычно делает посетитель, затем собрав вместе интересующие узлыВы можете перебирать их так же, как и любую другую коллекцию, которая предоставляет итераторы.В этот момент ваш шаблон посещения ограничен только классом итератора, предоставленным коллекцией, которую вы используете в своем мосту.