为什么 std::distance 击中了 stl 地图?

why std::distance struck in a stl map?

我想使用 std::distance 来查找我的元素的索引。

代码如下:

#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;
}

但我发现代码在 cout 中被击中了,我的代码有什么问题?

麻烦来自于 std::distance(first, last)...

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

所以你需要改成这样:

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

请注意,通过这种方式我们为 distance 提供了一个有效的 迭代器范围 。对构成迭代器范围的迭代器有要求:

  • 它们必须引用元素(或最后一个元素之后的元素) 同一个容器
  • 有可能通过重复递增begin达到end。在 换句话说,end 不能在 begin.
  • 之前

您的情况违反了第二个要求。

std::map的迭代器不是随机访问,那么对于std::distance()

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

因此 std::distance(it, m.begin()) 的行为未定义,m.begin()(指向第一个元素)无法通过递增 it(指向第二个元素)来访问。您应该改用 std::distance(m.begin(), it)