在这个 question 中,有人解释说,当给定无效的迭代器范围[first,last]时,std :: for_each具有未定义的行为(即,当通过先递增时无法到达last时)。
大概这是因为一般循环for(auto it = first; it != last; ++it)
将永远在无效范围上运行。但对于随机访问迭代器,这似乎是一个不必要的限制,因为随机访问迭代器有一个比较运算符,可以将显式循环写为for(auto it = first; it < last; ++it)
。这会将无效范围内的循环转换为无操作。
所以我的问题是:为什么标准不允许std :: for_each在无效的随机访问迭代器范围内有明确定义的行为?它将简化几种算法,这些算法仅对多元素容器有意义(例如,排序)。使用运算符&lt;()而不是operator!=()?
是否存在性能损失答案 0 :(得分:4)
答案 1 :(得分:2)
因为这是一般政策。所有使用<
都是允许的
像:
std::for_each( v.begin() + 20, v.begin() + 10, op );
即使使用<
,也传递无效的迭代器或来自不同的迭代器
容器,是未定义的行为。
答案 2 :(得分:2)
这会将无效范围上的循环转换为无操作。
您似乎在说operator<
应始终返回false
两个随机访问迭代器,这些迭代器不属于同一范围。这是你指定的循环是无操作的唯一方法。
指定此标准没有意义。请记住,指针是随机访问迭代器。考虑指针操作的实现负担,以及引起读者的一般混淆,如果定义以下代码打印“两个”:
int a[5];
int b[5]; // neither [a,b) nor [b,a) is a valid range
if ((a < b) || (b < a)) {
std::cout << "one\n";
} else {
std::cout << "two\n";
}
相反,它是未定义的,因此人们不会在第一时间写它。