为什么 std::distance() for std:list<int>::iterator 当 last 在 first 之前不返回负数?

Col*_*ell 4 c++ iterator stl stdlist undefined-behavior

std::distance在 上给我一个圆形距离std::list,而不是相对距离。为什么?

 #include <list>                                                                 
 #include <iostream>                                                             
 #include <iterator>                                                             

 using namespace std;                                                            

 int main(){                                                                     
     list<int> derp = {1,2,3,4};                                                 
     auto begin = derp.begin();                                                  
     auto end = derp.end();                                                      
     end--;                                                                      
     cout << distance(end, begin) << endl;                                       
     cout << distance(begin, end) << endl;                                       
}             
Run Code Online (Sandbox Code Playgroud)

当我运行它时,会发生以下输出:

2
3
Run Code Online (Sandbox Code Playgroud)

我期望以下内容:

-3
3
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

son*_*yao 5

您的代码具有未定义的行为。为了std::distance

如果InputIt不是LegacyRandomAccessIterator,如果last无法first通过(可能重复) incrementing到达,则行为未定义first。如果InputItLegacyRandomAccessIterator,则行为是未定义的,如果last不能从first并且first不能从 到达last

的迭代器std::list不是 RandomAccessIterator,并且begin无法end通过递增来访问它end

  • @CollinBell您可以使用`std::iterator_traits`检查迭代器类型是否是随机访问,但是给定两个指向相同序列的任意非随机访问迭代器,不可能判断哪个迭代器在另一个之前,因为它们不要实现`operator&lt;`。您将无法实现自己的。 (3认同)
  • @CollinBell AFAIK 没有这样的方法;对于所有 stl 容器和原始数组都是如此,它们的“end”可以通过递增从“begin”到达。`std::distance` 也不执行此类检测,如果无法访问则离开 UB。 (2认同)