简体   繁体   中英

why std::distance struck in a stl map?

I want to use std::distance to find the index of my element.

here is the code:

#include <iostream>
#include <map>
#include <iterator>
#include <string>
using namespace std;

int main() {
  std::map<int, std::string> m = {{1, "huang"}, {2, "wei"}, {3, "pu"}};
  auto it = m.find(2);
  cout << std::distance(it, m.begin()) << endl; // struck here
  cout << std::distance(it, m.end()) << endl;
}

but i found the code is struck in cout , what's the problem with my code?

The trouble comes from the fact that std::distance(first, last) ...

Returns the number of hops from first to last - cppreference.com

So you need to change to this:

// ...   
std::distance(m.begin(), it); // the number of hops from m.begin() to it
// ...

Note, that this way we present distance with a valid iterator range . There are requirements on iterators forming an iterator range:

  • They have to refer to elements (or one past the last element) of the same container
  • It is possible to reach end by repeatedly incrementing begin . In other words, end must not precede begin .

Where the second requirement was violated in your case.

Iterator of std::map is not random access, then for std::distance() ,

If InputIt is not LegacyRandomAccessIterator, the behavior is undefined if last is not reachable from first by (possibly repeatedly) incrementing first.

So the behavior of std::distance(it, m.begin()) is undefined, m.begin() (pointing to the 1st element) is not reachable by incrementing it (pointing to the 2nd element). You should use std::distance(m.begin(), it) instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM