Почему std :: distance () для std: list <int>:: iterator не возвращает отрицательное число, когда last находится перед first? - PullRequest
3 голосов
/ 27 сентября 2019

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;                                       
}             

Когда я запускаю это, происходит следующее:

2
3

Я ожидаю следующее:

-3
3

Почему это происходит?

Ответы [ 2 ]

4 голосов
/ 27 сентября 2019

Ваш код имеет неопределенное поведение.Для std::distance

Если InputIt не LegacyRandomAccessIterator , поведение не определено, если last недоступенс first путем (возможно, многократного) увеличения first.Если InputIt равно LegacyRandomAccessIterator , поведение не определено, если last недоступно с first и first недоступно с last.

Итератор std::list не является RandomAccessIterator, и его begin недоступен с end путем увеличения end.

0 голосов
/ 27 сентября 2019

Для итераторов, которые не удовлетворяют требованиям итератор с произвольным доступом , std::distance возвращает количество раз, которое first (первый аргумент) должно быть увеличено до равногоlast (второй аргумент).

Вы используете std::list, который не имеет итераторов произвольного доступа.В случае distance(end, begin), независимо от того, сколько раз вы увеличиваете end, оно никогда не будет равно begin.Таким образом, поведение не определено, и результат зависит от особенностей вашей стандартной реализации библиотеки.

...