我正在使用 std::reverse_iterator
今天正在考虑它如何处理通过在容器上调用 begin
创建的值。根据cppreference ,如果我有 reverse_iterator r
从 iterator i
构造,下面必须保持 &*r == &*(i-1)
。
但是,这意味着如果我写这个
std::vector<int> vec = {1, 2, 3, 4, 5};
auto iter = std::make_reverse_iterator(begin(vec));
iter 现在指向放置在 begin(vec)
之前的一 block 内存,这是越界的。根据 C++ 标准的严格解释,这会调用 UB。
(对于指向数组末尾 1 的元素的指针/迭代器有具体规定,但据我所知,没有针对指向元素 1 之前的指针/迭代器的规定数组的开始。)
那么,我在读 link 吗?错误,或者标准中是否有针对这种情况的特定规定,或者是在使用 reverse_iterator
时,整个数组被视为反转,因此指向数组前面的指针实际上是指针结束了吗?
最佳答案
是的,你读错了。
反向迭代器不需要存储指向元素开始之前的指针。
为了说明,取一个包含 2 个元素的数组:
int a[2];
这些是前向迭代器:
a+0 a+1 a+2 // The last one is not dereferenceable
反向迭代器将用这些完全相同的值以相反的顺序表示:
a+2 a+1 a+0 // The last one cannot be dereferenced
因此,虽然取消引用普通迭代器非常简单,但反向迭代器取消引用稍微复杂一些:pointer[-1]
(这是针对随机访问迭代器的,其他更糟: It copy = pointer; --copy; return *copy;
).
请注意,使用前向迭代器比使用反向迭代器要普遍得多,因此前者比后者更有可能为它们优化代码。由于体面的优化编译器所做的所有转换,没有触及那个角落的通用代码在任何一种类型上都可能运行得更好。
关于c++ - 为什么使用 `std::reverse_iterator` 不调用 UB?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25393017/