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值来影响这种行为,但它会产生一些库的二进制版本的问题,这些库是使用默认的调试设置构建的.
它并不是无害的... 尝试将迭代器移动过去是未定义的行为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)