为什么标准不允许 std::for_each 对无效的随机访问迭代器范围有明确定义的行为?
Why doesn't the standard allow std::for_each to have well-defined behavior on invalid random access iterator ranges?
在这个问题中,有人解释说,当给定一个无效的迭代器范围[first,last)时,std::for_each具有未定义的行为(即,当last不能通过先递增来访问时)。
这可能是因为一般循环for(auto it = first; it != last; ++it)
将永远在无效范围上运行。但对于随机访问迭代器来说,这似乎是一个不必要的限制,因为随机访问迭代器有一个比较运算符,可以将显式循环写成for(auto it = first; it < last; ++it)
。这将把一个无效范围的循环变成no-op。
所以我的问题是:为什么标准不允许std::for_each在无效的随机访问迭代器范围上有定义良好的行为?它将简化一些只对多元素容器(例如排序)有意义的算法。使用运算符<()而不是运算符=()?
这将把一个无效范围的循环变成no-op。
事实并非如此。
无效范围的一个示例是当first
和last
引用不同的容器时。比较这样的迭代器至少在某些情况下会导致未定义的行为。
这将把一个无效范围的循环变成no-op。
您似乎在说,对于不属于同一范围的两个随机访问迭代器,operator<
应该始终返回false
。这是你指定的循环成为no-op的唯一方法。
标准规定这一点是没有意义的。请记住指针是随机访问迭代器。想想指针操作的实现负担,以及给读者带来的普遍困惑,如果定义以下代码打印"两个":
int a[5];
int b[5]; // neither [a,b) nor [b,a) is a valid range
if ((a < b) || (b < a)) {
std::cout << "onen";
} else {
std::cout << "twon";
}
相反,它是未定义的,这样人们一开始就不会写它。
因为这是一般策略。所有使用<
都允许类似:
std::for_each( v.begin() + 20, v.begin() + 10, op );
即使使用<
,也会传递无效的迭代器或来自不同容器,是未定义的行为。
相关文章:
- 转到基于范围的 for 循环中的下一个迭代器
- C++:返回一个基于范围 for 循环迭代器,其中包含继承对象
- 迭代器范围的平衡分区,没有LegacyRandomAccessIterator
- 为什么范围算法与 std 的迭代器不兼容?
- Deque 迭代器超出范围
- unordered_set范围插入与迭代器
- 类型不可知的抽象以使用相同的运行时接口处理正向和反向迭代器和范围?
- 访问基于范围的循环(如for_each)中的std::map迭代器
- 迭代器的范围 TS 和 C++20 概念是否需要能够使用"运算符>"?
- 列出超出范围的擦除迭代器
- 如何使用提升范围将自定义迭代器封装在函数中
- 无法取消引用超出范围的向量迭代器 - 有什么问题?
- 如何在基于范围的 for 循环中更改(向前/向后移动)迭代器?
- 如何修复错误,迭代器未在此范围内声明,并且迭代器未命名类型'
- 将迭代器放置为临时范围时,非销钉 - 操作和错误
- C 迭代器范围使用指针到数组
- 为什么我们要把 :: (范围重新定位运算符)放在迭代器之前
- 将迭代器范围复制到矢量而不重复
- C++:指向错误元素的提升范围迭代器
- re C++范围迭代器:只有一个类不好吗