为什么std::distance会出现在stl地图中?
我想使用 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)......
返回从第一个到最后一个的跃点数 - cppreference.com
所以你需要改成这样:
// ...
std::distance(m.begin(), it); // the number of hops from m.begin() to it
// ...
请注意,通过这种方式,我们提供distance了一个有效的迭代器 range。对形成迭代器范围的迭代器有要求:
- 它们必须引用同一个容器的元素(或最后一个元素之后的元素)
- 可以
end通过重复递增来达到begin。换句话说,end不能在begin.
在您的情况下违反了第二个要求。
回答
的迭代器std::map不是随机访问,那么对于std::distance(),
如果 InputIt 不是 LegacyRandomAccessIterator,如果不能通过(可能重复)首先递增从第一个到达 last,则行为未定义。
所以 的行为std::distance(it, m.begin())是未定义的,m.begin()(指向第一个元素)不能通过递增it(指向第二个元素)来达到。你应该std::distance(m.begin(), it)改用。