"向量迭代器+偏移超出范围"断言是否有用?

Pau*_*zak 4 c++ stl visual-c++ visual-studio-debugging

这个完美的程序在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';
}
Run Code Online (Sandbox Code Playgroud)

vector iterator + offset out of range断言失败.它失败了,因为iTo > v.cend()这在这里是无害的.调试器测试迭代器的值有什么意义,它没有被解除引用?

顺便说一句,我知道我可以重写上面的循环:

for (auto i = v.cbegin(); i != v.cend(); i += 5)
  cout << *max_element(i, i+5) << '\n';
Run Code Online (Sandbox Code Playgroud)

但我试图用一段更复杂的现实代码做一个简单的例子,其中计算新的迭代器值在计算上是昂贵的.

我也意识到可以改变_ITERATOR_DEBUG_LEVEL值来影响这种行为,但它会产生一些库的二进制版本的问题,这些库是使用默认的调试设置构建的.

Ton*_*roy 9

它并不是无害的... 尝试将迭代器移动过去是未定义的行为end(),这是你在第三次也是最后一次迭代时所做的.在没有取消引用迭代器的情况下,在iTo += 5你这样做之后立即终止你的循环iFrom != v.cend()是不相关的.

如果效率确实是必要的,那么你就准备了银行对元素数量为5的倍数的赌注:

for (auto iFrom = v.cbegin(), iTo = iFrom; iFrom != v.cend(); iFrom = iTo)
{
    iTo += 5;
    cout << *max_element(iFrom, iTo) << '\n';
}
Run Code Online (Sandbox Code Playgroud)