如何解决std::reverse_iterator 是否适用于适应范围?
我记得读过 [forward.iterators]/6 的动机(要求,给定两个迭代器 a
和 b
,a == b
当且仅当 *a
和*b
绑定到同一个对象)是为了支持 reverse_iterator
。我没记错吗?
cppreference.com 注意到
对于由迭代器r
构造的反向迭代器i
,关系&*r == &*(i-1)
总是true
(只要r
是可解引用的);因此,一个反向迭代器由一个最后一个迭代器构造而成,它取消对序列中最后一个元素的引用。
还有:
std::reverse_iterator
不适用于其解引用返回对 *this
成员的引用的迭代器(所谓的“隐藏迭代器”)。一个隐藏迭代器的例子是 std::filesystem::path::iterator
。
不过,也有说明:
std::reverse_iterator
是一个迭代器适配器,它反转给定迭代器的方向,它必须至少是一个 LegacyBidirectionalIterator
或模型 bidirectional_iterator
(C++20 起)。
这正是标准的 says。
如果我没记错的话,C++20 bidirectional_iterator
不再需要 [forward.iterators]/6。例如,std::ranges::iota_view::iterator
是一个 std::random_access_iterator
,但也是一个隐藏迭代器。因此,如果上述关于隐藏迭代器的说法属实,我不明白为什么 std::bidirectional_iterator
是 std::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;
}
在 C++20 迭代器中使用 std::reverse_iterator
并没有多大意义,因为我们有 std::ranges::reverse_view
,但我很想知道 [forward.iterators]/6 当前是否完全有必要。
解决方法
关于隐藏迭代器的注意事项不是关于 *
的左值与右值返回,而是关于多遍保证。
std::forward_iterator
仍然具有语义要求“((void)[](auto x){ ++x; }(i),*i)
等价于 *i
”,decltype(v.begin())
满足,但不是(必须)由std::filesystem::path::
(const_
)iterator
满足。
const_iterator
一个具有 value_type
路径的常量 LegacyBidirectionalIterator,除了 {{1} 类型的可解引用迭代器 a
和 b
} 使用path::iterator
,不需要a == b
和*a
绑定到同一个对象
注意*b
被定义为(对于某些表达式)返回一个 std::reverse_view
,所以它仍然是相关的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。