[英]Why using `std::reverse_iterator` doesn't invoke UB?
我今天正在使用std::reverse_iterator
,并且正在考虑如何使用在容器上调用begin
创建的值。 根据cppreference ,如果我有从iterator i
构造的reverse_iterator r
,则以下必须保持&*r == &*(i-1)
。
但是,这意味着如果我写这个
std::vector<int> vec = {1, 2, 3, 4, 5};
auto iter = std::make_reverse_iterator(begin(vec));
iter现在指向begin(vec)
之前放置的内存begin(vec)
,这是超出范围的。 通过严格解释C ++标准,这将调用UB。
(指针/迭代器有一个特定的规定,指向数组的1-last-the-end-end,但据我所知,没有指针/迭代器到数组1的数字开头。)
所以,我读错了链接 ,或者这个案例的标准中是否有特定的规定,或者当使用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;
)。
请注意,使用forward-iterator比反向迭代器更常见,因此前者比后者更有可能为它们优化代码。 然而,由于所有转换都是一个不错的优化编译器,但是没有碰到那个角落的通用代码很可能在任何一种类型下运行得更好。
std::make_reverse_iterator(begin(vec))
不可解除引用,与end(vec)
不可解除引用的方式相同。 它没有“指向”任何有效的对象,这没关系。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.