我怎样才能将 std::map 的迭代器递减一定数量?
How can I go decrement the iterator of a std::map by a certain number?
有了 std::vector 我可以做到:
std::vector<int> h;
auto it = h.end() - 2;
但是 std::map 我做不到:
std::map<int, int> h;
auto it = h.end() - 2;
我只能做:
auto it = --h.end();
例如,如果我想要从末尾开始的成员二,或者从末尾开始的三,或者其他任何东西。
您可以使用 std::advance
:
auto it = h.end();
std::advance(it, -4);
请注意,对于 std::map
迭代器(不是随机访问迭代器),n
(第二个参数)的复杂度是 线性,这意味着没有 "magic" 并且调用 std::advance
相当于在迭代器上应用 n
次 increment/decrement 运算符。
另一方面,也可以使用std::prev
,如下:
auto it = std::prev(iter, 2);
在内部,这与 std::advance
做同样的事情(实际上是使用它),除了可以说这更清楚一些。
如果您想知道为什么不能像向量迭代器那样减去映射迭代器,这是因为 std::vector<T>::iterator
是一个 RandomAccessIterator, meaning it "can be moved to point to any element in constant time"1 through addition/subtraction. On the other hand, std::map<T,U>::iterator
is a BidirectionalIterator,它可以向任一方向移动,但是仅以一为增量。
1 http://en.cppreference.com/w/cpp/concept/RandomAccessIterator
模板 class std::vector
具有定义了操作 h.end() - 2
的随机访问迭代器。
另一方面,模板 class std::map
具有未定义操作 h.end() - 2
的双向迭代器。
如果包含 header <iterator>
,则可以使用标准函数 std::next
和 std::prev
作为随机访问迭代器和双向迭代器。
例如
#include <map>
#include <iterator>
//...
std::map<int, int> h;
//...
auto it = std::prev( h.end(), 2 );
和
#include <vector>
#include <iterator>
//...
std::vector<int> h;
//...
auto it = std::prev( h.end(), 2 );
有了 std::vector 我可以做到:
std::vector<int> h;
auto it = h.end() - 2;
但是 std::map 我做不到:
std::map<int, int> h;
auto it = h.end() - 2;
我只能做:
auto it = --h.end();
例如,如果我想要从末尾开始的成员二,或者从末尾开始的三,或者其他任何东西。
您可以使用 std::advance
:
auto it = h.end();
std::advance(it, -4);
请注意,对于 std::map
迭代器(不是随机访问迭代器),n
(第二个参数)的复杂度是 线性,这意味着没有 "magic" 并且调用 std::advance
相当于在迭代器上应用 n
次 increment/decrement 运算符。
另一方面,也可以使用std::prev
,如下:
auto it = std::prev(iter, 2);
在内部,这与 std::advance
做同样的事情(实际上是使用它),除了可以说这更清楚一些。
如果您想知道为什么不能像向量迭代器那样减去映射迭代器,这是因为 std::vector<T>::iterator
是一个 RandomAccessIterator, meaning it "can be moved to point to any element in constant time"1 through addition/subtraction. On the other hand, std::map<T,U>::iterator
is a BidirectionalIterator,它可以向任一方向移动,但是仅以一为增量。
1 http://en.cppreference.com/w/cpp/concept/RandomAccessIterator
模板 class std::vector
具有定义了操作 h.end() - 2
的随机访问迭代器。
另一方面,模板 class std::map
具有未定义操作 h.end() - 2
的双向迭代器。
如果包含 header <iterator>
,则可以使用标准函数 std::next
和 std::prev
作为随机访问迭代器和双向迭代器。
例如
#include <map>
#include <iterator>
//...
std::map<int, int> h;
//...
auto it = std::prev( h.end(), 2 );
和
#include <vector>
#include <iterator>
//...
std::vector<int> h;
//...
auto it = std::prev( h.end(), 2 );