问题标签 [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.

0 投票
1 回答
70 浏览

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()转换为“正常”迭代器。它需要转换返回的迭代器本身。

0 投票
1 回答
68 浏览

c++ - C ++中的反向迭代器和负跨步迭代器,在开始之前使用一个作为哨兵

另一种看待 C++ 反向迭代器的方式中, Raymond Chen 写道:

... C++ 语言的一个怪癖:您可以有一个指针“在集合的末尾”,但不允许您在集合的“开始之前”有一个指针。

我知道这可能意味着“未定义的行为”,这几乎是一个对话终结者。但我很好奇如果忽略这条规则,在现实系统中可能发生的最坏情况是什么。分段错误?指针算术溢出?不必要的分页?

请记住,开始“之前”的指针(如“end”)也不应该被引用,问题似乎是指针只是试图指向它。

我能想象的唯一可能出现问题的情况是内存位置“0”有效的系统。但即便如此,如果是这样的话,会有更大的问题,(例如 nullptr 本身也会有问题,我猜想按照惯例,环绕可能仍然有效。)

我不是在质疑reverse_iterator使用非一的特殊代码的实现。我想到了这个问题,因为如果你有一个“跨步”迭代器的通用实现,那么负跨步需要一个特殊的逻辑,并且有成本(在代码和运行时)。

任意步幅,包括负步幅,自然会出现在多维数组中。我有一个多维数组库,原则上我总是允许负步幅,但现在我意识到,如果我完全允许它们并且我不想暴露未定义的行为,它们应该有一个特殊的代码(不同于正例) .

0 投票
1 回答
153 浏览

c++ - 为什么 sort(rbegin(), rend()) 按降序对结构进行排序?

例如,下面的代码按 desc 顺序对 vec 进行排序:

C++ 参考

将 [first,last) 范围内的元素按升序排序。对于第一个版本,使用 operator< 比较元素 [...]

0 投票
2 回答
48 浏览

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()设计,

只是在相反的情况下。

所以我的问题是:做出确实已经做出的选择是否有明确的优势?或者它只是一枚翻转的硬币?