[英]How to inherit from c++ iterator class?
Below I depict the general structure of my code:下面我描述了我的代码的一般结构:
class OperandIterator : public std::iterator<std::input_iterator_tag, pOpReference>
{
public:
OperandIterator(...)...
OperandIterator & operator++(); // also calls to advance()
OperandIterator operator++(int); // also calls to advance()
bool operator==(const OperandIterator & other) const;
bool operator!=(const OperandIterator & other) const;
pOpReference operator*();
protected:
virtual void advance();
}
class OperandSpecialIterator : public OperandIterator
{
public:
...
private:
void advance() override; // this is the only diffrence between the classes
}
class TraversalPattern
{
public:
TraversalPattern(Operand op, Order order, bool specialTraversal);
OperandIterator begin() { return specialTraversal ? OperandSpecialIterator(...) : OperanInerator(...); }
}
// somewhere
TraversalPattern p(...specialTraversal=ture);
OperandIterator iter = p.begin();
it++;
Even though begin() function returns OperandSpecialIterator, when it++ performed the advance function that is being called is the advance function of OperandIterator.即使begin()函数返回OperandSpecialIterator,当it++执行时,被调用的advance函数是OperandIterator的advance函数。 The problem is that begin() can't return a reference.
问题是 begin() 不能返回引用。 The question is: Can begin function return iterators of different types?
问题是: begin 函数可以返回不同类型的迭代器吗?
What you are asking is not possible.你问的是不可能的。 The
begin()
function cannot return different types depending on a runtime value. begin()
函数不能根据运行时值返回不同的类型。 What you could do, is implement something like a VariantIterator
that can hold different types of operators in an std::variant
(C++17) and forwards the iterator operations to the currently held iterator.你可以做的是实现类似
VariantIterator
东西,它可以在std::variant
(C++17) 中保存不同类型的运算符,并将迭代器操作转发到当前保存的迭代器。
For this simple case, I personally would do the advancing by passing a function pointer to my Iterator:对于这个简单的情况,我个人会通过将函数指针传递给我的迭代器来进行推进:
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++;
The nice thing about this is, that you can easily add more versions of advancing and even make them in place with a lambda.这样做的好处是,您可以轻松添加更多版本的推进,甚至可以使用 lambda 使它们就位。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.