То, что вы спрашиваете, невозможно. Функция begin()
не может возвращать различные типы в зависимости от значения времени выполнения. Что вы могли бы сделать, это реализовать что-то вроде VariantIterator
, которое может содержать различные типы операторов в std::variant
(C ++ 17) и перенаправлять операции итератора текущему итератору.
В этом простом случае я бы лично продвинулся, передав указатель функции моему итератору:
class OperandIterator; // forward declaration
namespace advancers { // Forward declarations since definition only works,
// when OperandIterator is defined. You can make this easier by making
// these methods static in the class. I declare them forward to be able
// to use them as defaults in OperandIterator.
void advance_normally(OperandIterator& it);
void advance_specially(OperandIterator &it);
} // End namespace advancers
class OperandIterator : public std::iterator<std::input_iterator_tag, pOpReference>
{
public:
OperandIterator() = default;
OperandIterator(void (*advanc_fnc)(OperandIterator&)) : advancer(advanc_fnc) {}
OperandIterator & operator++(); // also calls advancer with *this
OperandIterator operator++(int); // also calls advancer with *this
private:
const void (*advancer)(OperandIterator&) = &advancers::advance_normally;
}
namespace advancers { // Definitions
void advance_normally(OperandIterator& it) {
it++;
}
void advance_specially(OperandIterator &it) {
// Something else
}
} // End namespace advancers
OperandIterator make_special() {
return OperandIterator(&advancers::advance_specially);
}
class TraversalPattern
{
public:
TraversalPattern(Operand op, Order order, bool specialTraversal);
OperandIterator begin() { return specialTraversal ? OperandSpecialIterator() : make_special(); }
}
// somewhere
TraversalPattern p(...specialTraversal=ture);
OperandIterator iter = p.begin();
it++;
Приятно то, что вы можете легко добавлять больше версий продвигаться и даже делать их на месте с помощью лямбды.