我刚注意到,对于迭代器类std::__detail::_Node_iterator
(在GCC的libstdc ++中,源here),我们有一个operator++()
但没有operator+()
,所以你可以使用{ {1}}但您无法使用(my_set.cbegin()++)++
。
为什么?它只是缺乏语法糖还是有更深层次的原因?
答案 0 :(得分:1)
当标准为O(n)时,标准不会提供operator+
,并且会让很多用户感到惊讶。
如果您准备支付费用,它确实提供了您可以使用的功能std::advance
。
答案 1 :(得分:1)
为什么?它只是缺乏语法糖还是有更深层次的原因?
理解这可能是我的一点推测(我没有设计/实现迭代器),我的想法是迭代器用于遍历具有某种程度的安全性的集合。写ssl_certificate
之类的东西会安全地将你从集合中的现有元素带到下一个元素,或者如果你已经到达终点,则会自动指向iterator++
。
它也比写null
或iterator = iterator + 1
短,这可能是将其限制为iterator += 1
的关键原因。添加所有这些似乎是多余的和不必要的。
引自C++ Reference(我的重点)
迭代器是指向某个范围内的某个元素的任何对象 元素(如数组或容器)具有迭代的能力 使用一组运算符通过该范围的元素( with at 至少增量(
++
)和解除引用(++
)运算符。
基于此,似乎是一个有意的架构决策,将客户端实现迭代器的要求保持在最低限度。请注意,基于上面的措辞(即“至少”),似乎没有技术原因可以解释为什么无法为其他运营商添加支持,包括{{1以外的比较运营商}}。他们是否可能是另一个讨论。
此外,迭代器通常会顺序遍历某个范围内的所有对象,因此在这种意义上允许*
似乎违背其预期目的。
例如,如果你做!=
,你怎么知道你不是要求收集器从迭代器的当前位置留下的更多东西?你可能试图超越集合的末尾并等待分段错误 - 或者他们需要开始抛出异常。迭代器安全地遍历集合而不会越界的能力是你在这里失去的一个好处,恕我直言。
迭代器仅用于保护客户端不受集合的实现细节的影响。也就是说,客户端不需要知道集合是实现为数组,某种链表还是某种树。它也不需要计算集合中有多少项,这使得它更容易实现和使用。 (它有一个责任。)
在此基础上,并牢记先前的“安全”和简约要求细节,避免实现对象可能支持的每个可能的操作员的决定对我来说是有意义的。