C++ 我可以通过添加一个数字来增加迭代器吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1033089/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I increment an iterator by just adding a number?
提问by Frank
Can I do normal computations with iterators, i.e. just increment it by adding a number?
我可以用迭代器进行正常的计算,即通过添加一个数字来增加它吗?
As an example, if I want to remove the element vec[3]
, can I just do this:
例如,如果我想删除元素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
It works for me (g++), but I'm not sure if it is guaranteedto work.
它对我有用(g++),但我不确定它是否能保证工作。
回答by Todd Gardner
It works if the iterator is a random access iterator, which vector's iterators are (see reference). The STL function std::advance
can be used to advance a generic iterator, but since it doesn't return the iterator, I tend use + if available because it looks cleaner.
如果迭代器是随机访问迭代器,则它可以工作,向量的迭代器是(请参阅参考资料)。STL 函数std::advance
可用于推进通用迭代器,但由于它不返回迭代器,我倾向于使用 + 如果可用,因为它看起来更干净。
C++11 note
C++11注意事项
Now there is std::next
and std::prev
, which doreturn the iterator, so if you are working in template land you can use them to advance a generic iterator and still have clean code.
现在有std::next
and std::prev
,它确实返回迭代器,所以如果你在模板领域工作,你可以使用它们来推进通用迭代器并且仍然有干净的代码。
回答by Nemanja Trifunovic
It works with random access iterators. In general you may want to look at std::advancewhich is more generic. Just be sure to understand performance implications of using this function template.
它适用于随机访问迭代器。一般来说,您可能想查看更通用的std::advance。请务必了解使用此函数模板的性能影响。
回答by Fred Schoen
A subtle point is that the operator+
takes a Distance
; i.e., a signed integer. If you increment the iterator by an unsigned, you may lose precision and run into a surprise. For example on a 64 bit system,
一个微妙的点是operator+
需要一个Distance
; 即,一个有符号整数。如果您将迭代器增加一个无符号数,您可能会失去精度并遇到意外。例如在 64 位系统上,
std::size_t n = (1 << 64) - 2;
std::vector<double> vec(1 << 64);
std::vector<double> slice(vec.begin() + n, vec.end());
leads to implementation-defined behavior. With g++
or clang
, you can ask the compiler to warn you about such undesired conversions with the warning flag -Wsign-conversion
that is not part of the canonical -Wall
or -Wextra
.
导致实现定义的行为。使用g++
或clang
,您可以要求编译器使用-Wsign-conversion
不属于规范-Wall
或-Wextra
.
A work-around is to work on the pointer directly
解决方法是直接处理指针
std::vector<double> slice(vec.data() + n, vec.data() + vec.size());
It's not pretty but correct. In some occasions, you need to construct the iterator manually, for example
它不漂亮但正确。在某些情况下,您需要手动构造迭代器,例如
std::vector<double>::iterator fromHere{vec.data() + n};
vec.erase(fromHere, vec.end());