为什么有些 libstdc++ 迭代器有 operator++ 但没有 operator+?

How come some libstdc++ iterators have operator++ but no operator+?

我刚刚注意到对于迭代器 class std::__detail::_Node_iterator(在 GCC 的 libstdc++ 中,来源 here),我们有一个 operator++() 但没有 operator+() , 所以你可以使用 (my_set.cbegin()++)++ 但你不能使用 my_set.cbegin() + 2.

这是为什么?是缺少语法糖还是有更深层次的原因?

该标准不提供 operator+ 的时间复杂度为 O(n),这会让很多用户感到惊讶。

它确实提供了一个功能std::advance,如果您愿意支付费用,您可以使用。

Why is that? Is it just lack of syntactic sugar or is there a deeper reason?

理解这对我来说可能有点推测(我没有 design/implement 迭代器),我的想法是迭代器旨在以某种程度 安全性遍历集合。编写类似 iterator++ 的内容将安全地将您从集合中的现有元素带到下一个,或者如果您已经到达终点,则自动指向 null

它也比写 iterator = iterator + 1iterator += 1 短,这可能是将其限制为仅 ++ 的关键原因。把它们都加起来似乎是多余的和不必要的。

引自C++ Reference(我的重点)

An iterator is any object that, pointing to some element in a range of elements (such as an array or a container), has the ability to iterate through the elements of that range using a set of operators (with at least the increment (++) and dereference (*) operators).

基于此,将实现迭代器的客户端要求保持在最低限度似乎是一个有意的架构决策。请注意,根据上面的措辞(即 "at least"),似乎没有技术原因可以说明为什么有人 不能 添加对其他运算符的支持,包括比较运算符 other比 !=。他们是否应该可能是另一个讨论。

此外,迭代器通常会依次遍历某个范围内的所有对象,因此允许iterator + X在这个意义上似乎违背了其预期目的。

例如,如果您这样做 iterator + 2,您怎么知道您要求的不是集合从迭代器当前位置真正剩下的东西?您可能试图越过集合的末尾并等待分段错误——或者他们需要开始抛出异常。迭代器 安全地 遍历集合而不越界的能力是你在这里失去的一个好处,恕我直言。

迭代器只是为了保护客户端不受集合的实现细节的影响。也就是说,客户端不需要知道集合是作为数组、某种链表还是某种树实现的。它也不需要计算集合中有多少项,这再次使其更容易实现和使用。 (它只有一个职责。)

基于此,并牢记之前的 'safety' 和简约的需求细节,避免实现对象可能支持的每个可能运算符的决定对我来说很有意义。