是“向量迭代器+偏移量超出范围"吗?断言有用吗? [英] Is "vector iterator + offset out of range" assertion useful at all?
问题描述
这个完美的程序在 Visual Studio 2013 的调试模式下失败:
This perfectly good program fails in debug mode in Visual Studio 2013:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void main()
{
vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3};
for (auto iFrom = v.cbegin(), iTo = iFrom+5; iFrom != v.cend(); iFrom = iTo, iTo += 5)
cout << *max_element(iFrom, iTo) << '\n';
}
with vector iterator + offset out of range
断言失败.它失败是因为 iTo >v.cend()
,这里是无害的.调试器测试迭代器的值有什么意义,它没有被取消引用?
with vector iterator + offset out of range
assertion failure. It fails because iTo > v.cend()
, which is harmless here. What is the point of debugger testing the value of iterator, which is not being dereferenced?
顺便说一句,我知道我可以将上面的循环重写为:
BTW, I know that I can rewrite the loop above as:
for (auto i = v.cbegin(); i != v.cend(); i += 5)
cout << *max_element(i, i+5) << '\n';
但我试图用一段更复杂的现实生活代码制作一个简单的例子,其中计算新的迭代器值在计算上是昂贵的.
but I was trying to make a simple example out of a piece of more complex real-life code, where calculating the new iterator value is computationally expensive.
我也意识到可以更改 _ITERATOR_DEBUG_LEVEL
值来影响这种行为,但这会导致某些库的二进制版本出现问题,这些库是使用默认调试设置构建的.
I also realize that one can change _ITERATOR_DEBUG_LEVEL
value to affect this behavior, but it creates problems with binary versions of some libraries, which are built with default debug settings.
推荐答案
这不是无害的...它是未定义的行为试图将迭代器移过 end()
,您在第三次也是最后一次迭代中执行的操作.在使用 iTo += 5
执行此操作后,您立即以 iFrom != v.cend()
终止循环而不取消引用迭代器这一事实无关紧要.
It's not harmless... it's undefined behaviour to attempt to move the iterator past end()
, which you do on your third and final iteration. The fact that immediately after doing so with iTo += 5
you terminate your loop as iFrom != v.cend()
without dereferencing the iterator is not relevant.
如果确实需要效率,并且您准备好让银行押注元素数量是 5 的倍数:
If efficiency is really necessary and you're prepared the bet the bank on the number of elements being a multiple of 5:
for (auto iFrom = v.cbegin(), iTo = iFrom; iFrom != v.cend(); iFrom = iTo)
{
iTo += 5;
cout << *max_element(iFrom, iTo) << '\n';
}
这篇关于是“向量迭代器+偏移量超出范围"吗?断言有用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!