我最近在
std::distance
上遇到了奇怪的行为。它没有给出预期的结果,或者我理解不正确。标准没有对此提供太多细节https://en.cppreference.com/w/cpp/iterator/distance
这里是示例代码或在线运行:
#include <iostream>
#include <iterator>
#include <list>
int main()
{
std::list<int> v{1, 2, 1};
auto it1 = v.begin(); // points to 1
auto it2 = std::next(it1); // points to 2
std::cout<<std::distance(it2, it1)<<std::endl;
std::cout<<*it2<<std::endl;
std::cout<<std::distance(it2, it1)<<std::endl;
}
如果使用 C++17 编译,
输出为:
1
2
3
但我希望它是:
-1
2
-1
那么为什么
std::distance
不会给出负值,为什么第二次调用 std::distance
会给出不同的结果?
您正在测量指针之间的距离(以元素偏移量表示),而不是指针所指向的位置之间的距离。
您的数据布局类似于:
Address
0x0234230 1
0x0234234 2
0x0234238 1
这意味着 it1 保存值
0x0234230
并且在初始赋值时 it2 保存值 0x0234234
这两者之间的区别(在我的示例中)是
0x0000004
或 4 个字节,但它具有指针数据类型,其长度为 4
字节(在我的示例中),因此它是 4/4
项长,或者距离1
当您第二次调用该项目时,std::next(...) 赋值会递增指向下一个元素的指针,现在指针中的地址为
0x0234238
,字节差为 8
指数差为 2
当您第三次调用该项目时,上面的 std::next(...) 赋值会触发自动增量,并且您的值是
0x023423A
(十六进制),最终会产生 3
的距离。
您想要做的是获取值的距离。 这意味着您无法计算指针的距离,您需要计算指针所在地址处的元素的距离。
当你第三次调用该项目时,你会重复上面的错误,并且你会得到相同的指针之间的距离(索引距离)。