c++ - 为什么使用 `std::reverse_iterator` 不调用 UB?

标签 c++ stl iterator

我正在使用 std::reverse_iterator今天正在考虑它如何处理通过在容器上调用 begin 创建的值。根据cppreference ,如果我有 reverse_iterator riterator 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/

相关文章:

Python 在 __new__ 方法中检查可迭代

c++ - 在可移植 C++ 构造的引用上使用 "operator &"吗?

c++ - 如何使用 QT 和 C++ 启动应用程序

c++ - make_pair 如何隐式推断类型?

c++ - 使用 STL 在两个排序范围内查找第一个匹配项

java - 迭代列表的最佳方法是什么

c++ - 在 C++ 中发生没有匹配函数调用错误

c++ - 如何防止连续循环 #include 语句?

c++ - 在 C++ 中表示 BLOB

java - 显示存储在 HashMap 中的对象值