让我们考虑一个非常基本的范围适配器类,它围绕一个范围并在您迭代适配器时迭代原始范围的所有其他元素。
for (const auto & e : everyOtherElement(originalRange))
在编写这样一个范围适配器类时,需要为该适配器编写一个相应的迭代器类,以使其可迭代并表现得像期望的那样。
这样的迭代器类应该实现您希望它支持的“概念”所需的所有内容,例如InputIterator
. 除其他外,我们应该实现operator*
返回对所表示元素的引用,以及访问operator->
该it->member
元素的成员。
我认为将这些运算符简单地“转发”到适配器包裹的底层迭代器的实现是一个好主意(让我们暂时忘记 const-ness):
struct everyOtherElement {
OriginalIterator b, e; // The begin and end we wrap around
// ...
struct iterator {
OriginalIterator it;
auto operator*() { return *it; } // <------
auto operator->() { return it.operator->(); } // <------
// ...
};
};
但是,如果是指针类型,则operator->
无法编译,就像大多数实现一样,当然还有原始数组。因为这样的迭代器是非类类型,所以不允许写.OriginalIterator
std::vector
it.operator->()
我应该如何实现operator->
以使迭代器尽可能透明?我是否应该operator->
根据. 我想如果某些迭代器将它们实现为不同的东西,这将失败......(虽然那会是邪恶的,不是吗?或者这是概念所禁止的?)operator*
(*it).m
it->m
InputIterator
将其实现为仅返回原始迭代器是否是个好主意,因为operator->
只要返回非指针就会自动递归应用?
auto operator->() { return it; }