问题标签 [reverse-iterator]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 带有反向迭代器的 STL 算法函数不起作用
我需要在我的数组中找到最小元素,但是如果最小元素的数量超过 1,我需要使用最正确的元素。
考虑这段代码:
它不起作用。这对我来说没有意义。Reverse_iterator 基本上提供了正确执行函数所需的所有运算符。但显然min_element()
只期望给出“正常”迭代器。我能以某种方式绕过它吗?好的,我可以使用.base()
函数成员 ( min_element(a.rbegin().base(), a.rend().base())
) 将我的 reverse_iterator 转换为迭代器,但这并不能解决我的问题,因为operator+
现在是向前而不是向后。我想不出任何明智的办法。这个问题有优雅的解决方案吗?
PS有一个自定义比较器问题的解决方案,它适用于普通迭代器,但我仍然想知道是否有reverse_iterators的解决方案:
vector<int>::iterator it_min = min_element(a.begin(), a.end(), [](int min, int b) { return min >= b; });
UPD:在回答之后,我明白我所说的关于 min_element() 的一切都是错误的。它可以接受 reverse_iterators 并正确使用它们,但我很困惑为什么它需要将 reverse_iterators 转换为迭代器,但它不需要a.rbegin()
anda.rend()
转换为“正常”迭代器。它需要转换返回的迭代器本身。
c++ - C ++中的反向迭代器和负跨步迭代器,在开始之前使用一个作为哨兵
在另一种看待 C++ 反向迭代器的方式中, Raymond Chen 写道:
... C++ 语言的一个怪癖:您可以有一个指针“在集合的末尾”,但不允许您在集合的“开始之前”有一个指针。
我知道这可能意味着“未定义的行为”,这几乎是一个对话终结者。但我很好奇如果忽略这条规则,在现实系统中可能发生的最坏情况是什么。分段错误?指针算术溢出?不必要的分页?
请记住,开始“之前”的指针(如“end”)也不应该被引用,问题似乎是指针只是试图指向它。
我能想象的唯一可能出现问题的情况是内存位置“0”有效的系统。但即便如此,如果是这样的话,会有更大的问题,(例如 nullptr 本身也会有问题,我猜想按照惯例,环绕可能仍然有效。)
我不是在质疑reverse_iterator
使用非一的特殊代码的实现。我想到了这个问题,因为如果你有一个“跨步”迭代器的通用实现,那么负跨步需要一个特殊的逻辑,并且有成本(在代码和运行时)。
任意步幅,包括负步幅,自然会出现在多维数组中。我有一个多维数组库,原则上我总是允许负步幅,但现在我意识到,如果我完全允许它们并且我不想暴露未定义的行为,它们应该有一个特殊的代码(不同于正例) .
c++ - 为什么是 reverse_iterator::base 偏移量?
(ASCII 从这个答案中复制和编辑,这实际上是提示我提出当前问题。)
我确实看到了它的好处&*rit == &*(rit.base() - 1)
,因为这样我可以将rit.base()
用于任何反向迭代器rit
,并且我总是会得到一个有效的迭代器。
但同时
- 我不能取消引用
v.rbegin().base()
;我必须记得先减去 1,*(v.rbegin().base() - 1)
, - 我不能完全取消引用
v.rend().base() - 1
,因为我不能取消引用v.rend()
。
如果设计就是这样&*rit == &*rit.base()
呢?
- 我们不能调用, 是的,但这只是对应于当前设计
v.rend().base()
中无法取消引用;v.rend().base() - 1
- 我们将无法
v.end()
直接从反向迭代器中获取,甚至不能从最接近的迭代器中获取b.rbegin()
,但- 1
我们必须rit.base()
在当前设计中添加到以获取与反向相同元素的正向迭代器。
我的意思是,在我看来,无论设计决定是那个&*rit == &*(rit.base() - 1)
(原样)还是那个&*rit == &*rit.base()
,我们都会有同样的便利
rit.base()
在实际设计中总是可以的,- 1
在替代设计中通常不需要
和不便
- 不能取消引用
rit.base()
实际设计中的所有有效 s, - 需要进入
+1
v.rbegin()
替代v.end()
设计,
只是在相反的情况下。
所以我的问题是:做出确实已经做出的选择是否有明确的优势?或者它只是一枚翻转的硬币?