为啥 std::distance 在 stl 地图中被击中?
Posted
技术标签:
【中文标题】为啥 std::distance 在 stl 地图中被击中?【英文标题】:why std::distance struck in a stl map?为什么 std::distance 在 stl 地图中被击中? 【发布时间】:2021-06-24 06:38:59 【问题描述】:我想使用 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(m.begin(), it)
。
如果 last 不能通过(可能重复)从 first 递增 first 到达,则行为未定义。 distance ref
如果编译器没有推断出行为未定义,而是代码尝试递增it
,直到达到m.begin()
,这将需要很长时间。或者这需要很短的时间,但风扇可能会加速。
【参考方案1】:
问题在于std::distance(first, last)
...
返回从第一个到最后一个的跃点数 - cppreference.com
所以你需要改成这样:
// ...
std::distance(m.begin(), it); // the number of hops from m.begin() to it
// ...
注意,通过这种方式,我们为distance
提供了一个有效的迭代器范围。对构成迭代器范围的迭代器有要求:
begin
来达到end
。在
换句话说,end
不能在 begin
之前。
在您的案例中违反了第二个要求。
【讨论】:
【参考方案2】:std::map
的迭代器不是随机访问的,那么对于std::distance()
,
如果 InputIt 不是 LegacyRandomAccessIterator,则如果 last 不能通过(可能重复)先递增从第一个到达,则行为未定义。
所以std::distance(it, m.begin())
的行为是未定义的,m.begin()
(指向第一个元素)不能通过递增it
(指向第二个元素)来达到。你应该改用std::distance(m.begin(), it)
。
【讨论】:
以上是关于为啥 std::distance 在 stl 地图中被击中?的主要内容,如果未能解决你的问题,请参考以下文章
在std :: list中,std :: distance(it.begin(),std :: prev(it.end())是否等于list.size()? [重复]