我可以通过添加一个数字来增加迭代器吗?

Fra*_*ank 41 c++ iterator

我可以使用迭代器进行正常计算,即只需通过添加数字来增加它吗?

例如,如果我想删除元素vec[3],我可以这样做:

std::vector<int> vec;
for(int i = 0; i < 5; ++i){
      vec.push_back(i);
}
vec.erase(vec.begin() + 3); // removes vec[3] element
Run Code Online (Sandbox Code Playgroud)

它适用于我(g ++),但我不确定它是否可以保证工作.

Tod*_*ner 46

如果迭代器是一个随机访问迭代器,它的向量迭代器是(参见参考资料).STL函数std::advance可用于推进通用迭代器,但由于它不返回迭代器,我倾向于使用+如果可用,因为它看起来更干净.

C++ 11注意

现在有std::nextstd::prev,它返回的迭代器,所以如果你是在模板土地工作,你可以用它们来推动通用的迭代,仍然有干净的代码.

  • 正确; 添加了一些文档链接,列出哪些函数应该可用于哪些类型的迭代器. (2认同)
  • 不,事实并非如此。+ 运算符的意思是“一步一步地向前跳这么远”,这是列表迭代器无法做到的。前向非随机访问迭代器(如列表迭代器)仅支持增量 (++) 运算符一次前进一个元素。正如 Todd 所说,您可以使用 std::advance 来重复调用 ++ 运算符,以简洁地表达将非随机迭代器向前移动多个步骤的想法。 (2认同)
  • 值得指出的是,在某些情况下,使用+和std :: list迭代器时的编译错误比std :: advance更有效*.如果你在向量中推进任意数量的位置(不仅仅是这里的一个位置)并且需要在恒定时间内进行,那么有人将容器更改为列表,这可能是您想要捕获的错误.最好在编译时捕获它,而不是在你注意到以后的糟糕性能时(可能是生产!).此外,使用+而不是std :: advance文档期望它是一个恒定时间操作. (2认同)

Fre*_*oen 5

一个微妙的点是,operator+需要 a Distance; 即有符号整数。如果您将迭代器增加一个无符号数,您可能会失去精度并遇到意外。例如在 64 位系统上,

std::size_t n = (1 << 64) - 2;
std::vector<double> vec(1 << 64);
std::vector<double> slice(vec.begin() + n, vec.end());
Run Code Online (Sandbox Code Playgroud)

导致实现定义的行为。使用g++or clang,您可以要求编译器使用-Wsign-conversion不属于规范-Wallor一部分的警告标志来警告您此类不需要的转换-Wextra

解决方法是直接处理指针

std::vector<double> slice(vec.data() + n, vec.data() + vec.size());
Run Code Online (Sandbox Code Playgroud)

它不漂亮但是正确。在某些情况下,您需要手动构造迭代器,例如

std::vector<double>::iterator fromHere{vec.data() + n};
vec.erase(fromHere, vec.end());
Run Code Online (Sandbox Code Playgroud)