为什么对 std::distance 的第二次调用会给出不同的结果?

问题描述 投票:0回答:1

我最近在

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
会给出不同的结果?

c++ iterator c++17 c++20
1个回答
0
投票

您正在测量指针之间的距离(以元素偏移量表示),而不是指针所指向的位置之间的距离。

您的数据布局类似于:

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
的距离。

您想要做的是获取值的距离。 这意味着您无法计算指针的距离,您需要计算指针所在地址处的元素的距离。

当你第三次调用该项目时,你会重复上面的错误,并且你会得到相同的指针之间的距离(索引距离)。

© www.soinside.com 2019 - 2024. All rights reserved.