C++ 为什么std::distance()用于std:list<;int>;::当last在first之前时,迭代器不返回负数?

C++ 为什么std::distance()用于std:list<;int>;::当last在first之前时,迭代器不返回负数?,c++,stl,iterator,undefined-behavior,stdlist,C++,Stl,Iterator,Undefined Behavior,Stdlist,std::distance给出了std::list上的圆形距离,而不是相对距离。为什么? #include <list> #include <iostream> #include <iterator>

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;                                       
}             
我期望:

-3
3

为什么会这样

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

如果
InputIt
不是,则如果通过(可能重复)递增
first
无法从
first
访问
last
,则行为是未定义的。如果
InputIt
为,则如果
last
无法从
first
访问,并且
first
无法从
last
访问,则行为未定义


std::list
的迭代器不是RandomAccessIterator,它的
begin
不能通过增加
end
来从
end
访问。对于不满足a要求的迭代器,返回
first
(第一个参数)必须增加到等于
last
的次数(第二个论点)


您使用的是没有随机访问迭代器的,无论你增加多少次
end
,它永远不会等于
begin
。因此,行为是未定义的,结果取决于你的标准库实现的细节。

好的。有没有一种标准方法来检测最后一个是否可以通过增加从第一个到达?我可能只需要实现my own.@CollinBell AFAIK没有这样的方法;对于所有stl容器和原始数组都是这样,它们的
end
可以通过递增从
begin
访问。
std::distance
也不执行这种检测,如果无法访问,就离开UB。@CollinBell您可以使用
std::iterator\u traits
,但是给定两个指向同一序列的任意非随机访问迭代器,不可能区分哪一个在另一个之前,因为它们没有实现
运算符。为什么您希望
std::distance(begin,end)
的结果是
3
?我实际上希望
4
-3
3