我今天读到关于支持双向迭代的容器,这段代码是有效的:
Collection c(10, 10);
auto last = --c.end();
*last;
这让我开始思考,是否需要在将一对双向迭代器 [beg, end) 提交给 STL 中定义了 --end 的算法时?如果是这样,结果应该是可取消引用的吗?
即
void algo(T beg, T end){
//...
auto iter = --end;
//...
*iter;
}
最佳答案
如果算法需要由双向迭代器 first
和 last
定义的范围,则 --last
需要在相同条件下有效++first
所做的——即范围不为空。当且仅当 first == last
时,范围为空。
如果范围不为空,则 --last
计算为引用范围中最后一个元素的迭代器,因此 *--last
确实也是需要有效。
也就是说,并没有那么多标准算法特别需要双向迭代器(并且不需要随机访问)。 prev
, copy_backward
, move_backward
, reverse
, reverse_copy
, stable_partition
, inplace_merge
, [prev|next]_permutation
.
如果您查看其中一些函数的作用,您应该会发现算法通常会递减范围结束迭代器并取消引用结果。
正如 James 所说,对于容器,end()
函数返回一个按值 的迭代器。对于迭代器,当 x
是类型的右值时,--x
应该是格式正确的表达式没有一般要求。例如,指针是双向迭代器,声明为 int *foo();
的函数按值返回一个指针,而 --foo()
不是一个很好的-形成的表达。碰巧的是,对于您在实现中查看的容器,end()
返回一个类类型,该类类型将 operator--
定义为成员函数,并且所以代码编译。它也可以工作,因为容器不是空的。
请注意,在这方面之间存在差异:
auto last = --c.end();
对比
auto last = c.end();
--last;
前者递减一个右值,而后者递减一个左值。
关于c++ - 递减结束迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12057046/