我可以使用迭代器进行正常计算,即只需通过添加数字来增加它吗?
例如,如果我想删除元素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
它适用于我(g ++),但我不确定它是否保证能够正常工作。
答案 0 :(得分:46)
如果迭代器是一个随机访问迭代器,它的向量迭代器是(参见reference)。 STL函数std::advance
可用于推进泛型迭代器,但由于它不返回迭代器,因此我倾向于使用+,因为它看起来更干净。
C ++ 11 note
现在有std::next
和std::prev
,其中做返回迭代器,所以如果你在模板领域工作,你可以使用它们来推进通用迭代器有干净的代码。
答案 1 :(得分:2)
它适用于随机访问迭代器。一般来说,您可能希望查看更为通用的std::advance。请务必了解使用此功能模板的性能影响。
答案 2 :(得分:0)
一个微妙的地方是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());
导致未定义的行为。使用g++
或clang
,您可以要求编译器通过警告标志-Wsign-conversion
来警告您这种不受欢迎的转换,该警告标志不属于规范的-Wall
或{{1 }}。
一种解决方法是直接在指针上工作
-Wextra
这不漂亮,但正确。在某些情况下,您需要手动构造迭代器,例如
std::vector<double> slice(vec.data() + n, vec.data() + vec.size());
答案 3 :(得分:0)
只有使用随机访问迭代器(例如 std::vector 和 std::deque 中的迭代器)才能进行数字运算。
std::vector<int>list={1,2,3,4,5,6,7,8};
auto last_v=*(list.end()-1);
auto third_last_v=*(list.end()-3);
std::cout<<"Last & 3rd last entry for vector:"<<last_v<<","<<third_last_v<<std::endl;
将输出 8 和 6,但是对于具有双向迭代器的 std::map、std::multimap、std::set、std::multiset
std::map<int,std::string> map_={{1,"one"},{2,"two"},{3,"three"}};
auto last_mp=*(map_.end()-1);
auto third_last_mp=*(map_.end()-3);
std::cout<<"Last & 3rd last entry for map:("<<last_mp.first<<","<<last_mp.second<<") and ("<<third_last_mp.first<<","<<third_last_mp.second<<")"<<std::endl;
会导致
error: no match for ‘operator-’ (operand types are ‘std::map, int>::iterator {aka std::_Rb_tree_iterator, int> >}’ and ‘int’)
对于双向迭代器 std::next()、std::prev 或 std::advance() 有效
std::map<int,std::string> map_={{1,"one"},{2,"two"},{3,"three"}};
auto last_mp=*std::prev(map_.end(),1);
auto third_last_mp=*std::prev(map_.end(),3);
std::cout<<"Last & 3rd last entry for map:("<<last_mp.first<<","<<last_mp.second<<") and ("<<third_last_mp.first<<","<<third_last_mp.second<<")"<<std::endl;
将输出 (3,three) 和 (1,one)。同样,std::unordered_map 有一个前向迭代器,所以这里使用 std::next() 是有意义的。