std::reverse_iterator 是否适用于调整后的范围?

Does std::reverse_iterator work with adapted ranges?

我记得读过 [forward.iterators]/6 的动机(要求,给定两个迭代器 aba == b 当且仅当 *a*b 绑定到同一个对象)是为了支持 reverse_iterators。我没记错吧?

cppreference.com 注意到

For a reverse iterator r constructed from an iterator i, the relationship &*r == &*(i-1) is always true (as long as r is dereferenceable); thus a reverse iterator constructed from a one-past-the-end iterator dereferences to the last element in a sequence.

还有:

std::reverse_iterator does not work with iterators whose dereference returns a reference to a member of *this (so-called "stashing iterators"). An example of a stashing iterator is std::filesystem::path::iterator.

不过,也说明:

std::reverse_iterator is an iterator adaptor that reverses the direction of a given iterator, which must be at least a LegacyBidirectionalIterator or model bidirectional_iterator (since C++20).

这正是标准 says

如果我没记错的话,C++20 bidirectional_iterators 不再需要 [forward.iterators]/6。例如,std::ranges::iota_view::iterator 是一个 std::random_access_iterator 但也是一个存储迭代器。因此,如果上述关于隐藏迭代器的声明是正确的,我不明白为什么 std::bidirectional_iteratorstd::reverse_iterator 工作的充分要求。

确实,以下程序显示了预期的输出:

#include <iostream>
#include <ranges>

int main()
{
  auto v = std::views::iota(0u, 10'000ul) | std::views::take(10);

  for (auto it = std::make_reverse_iterator(v.end());
       it != std::make_reverse_iterator(v.begin()); ++it)
    std::cout << *it << std::endl;
}

std::reverse_iterator 与 C++20 迭代器一起使用并没有多大意义,因为我们有 std::ranges::reverse_view,但我很想知道 [forward.iterators] /6 目前是必需的。

关于隐藏迭代器的注释不是关于 * 中的左值与右值 return,而是关于多遍保证。

std::forward_iterator 仍然有语义要求“((void)[](auto x){ ++x; }(i), *i) 等同于 *i”, 满足 decltype(v.begin()) , 但不(必须)符合 std::filesystem::path::(const_)iterator.

const_iterator a constant LegacyBidirectionalIterator with a value_type of path, except that for dereferenceable iterators a and b of type path::iterator with a == b, there is no requirement that *a and *b are bound to the same object

N.b。 std::reverse_view 被(对于某些表达式)定义为 return a ranges::subrange<reverse_iterator<...>>,所以它仍然是相关的。