【发布时间】:2014-05-07 10:32:19
【问题描述】:
对于 VS2013 中的调试模式,如果我向迭代器添加一个常量值并且该迭代器之后将超出范围,则会收到超出范围的异常。
例如:
#include <cstdlib>
#include <vector>
int main(void) {
std::vector<unsigned char> data(10, 0);
auto it = data.begin();
while (it != data.end()) {
if ((it + 3) <= data.end()) {
it += 3;
}
else {
it = data.end();
}
}
return EXIT_SUCCESS;
}
在while-loop 的第四次运行中,检查it + 3 <= data.end() 失败并抛出异常。
VS 编译器的一个简短解决方法是插入 #define _ITERATOR_DEBUG_LEVEL 0,以在调试模式下禁用检查迭代器的选项。
但我希望有一个更好、更通用的解决方案,它适用于 VS 和 GCC 编译器! 我确信 STL 已经存在一种方法来处理迭代器距离和这样的检查:) 但我还不知道......
【问题讨论】:
-
为什么不
for (auto it = data.begin(); std::distance(it, data.end()) > 3; it += 3){//your loop} -
第一个元素之前或最后一个元素之后的迭代器 + 1 是未定义的行为。 (请注意,仅获取此迭代器——即使没有取消引用它——也是 UB)
-
注意:编译器的抱怨是因为你在做一些“非法”的事情,这只是一个症状,因此你的解决方法并不是真正的:你交易的是一个易于理解且可重现的未定义集合的症状。