Как сравнить (порядок) двух двунаправленных итераторов?

Мне было интересно, есть ли встроенный способ в C ++ для сравнения порядка двух двунаправленных итераторов. Например, у меня есть функция Sum для вычисления суммы между двумя итераторами в одном и том же списке:

double Sum(std::list::const_iterator Start, std::list::const_iterator End){
double sum=0;
for (Start;Start!=End;Start++)
sum+=*Start;
return sum;
}

Затем:
Sum(my_list.begin(),my_list.end()); хорошо, но Sum(my_list.end(),my_list.begin()); вызовет ошибку во время выполнения.

Я думал положитьif (Start>End) return 0; чтобы предотвратить ошибку. Но, похоже, я не могу сравнить итераторы, как это.

1

Решение

Вы должны прочитать Введение в STL который объясняет различные уточнения концепции итератора.

Только RandomAccessIterators поддержка сравнения с < потому что это не эффективная операция для не-RandomAccessIterators.

Единственный способ сказать, если BidirectionalIterator i меньше, чем другой, j, увеличивая i один шаг за раз и посмотреть, если вы когда-нибудь достигнете j, но этого никогда не произойдет, если j недоступен из iи является ошибкой, если i не увеличивается, например потому что это последний итератор для диапазона.

В качестве альтернативы, вы можете уменьшить i и посмотрим, достигнете ли вы jв каком случае вы знаете j меньше чем i, но это не сработает, если i является начальным итератором, потому что вы не можете выполнять итерацию до начала диапазона.

Таким образом, в общем, нет никакого способа узнать, приходит ли один не-RandomAccessIterator до или после другого, потому что вы даже не можете знать, начинать ли итерацию вперед или назад, чтобы достичь другого, и вы не будете знать, когда это безопасно продолжать или когда вы достигнете конца допустимого диапазона.

Таким образом, по соглашению вы всегда передаете итераторы в одном и том же порядке, так что начальный итератор идет первым, а последний итератор — вторым, а конечный итератор может быть достигнут путем увеличения нуля начального итератора или больше раз.

Затем: Sum(my_list.begin(),my_list.end()); хорошо, но Sum(my_list.end(),my_list.begin()); вызовет ошибку во время выполнения.

Тогда не делай этого!

Ответственность за правильный вызов функции лежит на вызывающей стороне, и почему вызывающая сторона не знает, какой итератор является началом, а какой — концом?

4

Другие решения

когда вы вызываете Sum (my_list.begin (), my_list.end ()), my_list.begin () будет указывать на первый элемент в списке

double Sum(std::list::const_iterator& Start, std::list::const_iterator& End)
{
double sum=0;
if (Start;Start!=End;Start++)
sum+=*Start;
return sum;
}

SameWay, когда вы звоните Сумма (my_list.end (), my_list.begin ()),my_list.end () будет указывать на последний элемент в списке.

Сделайте ниже изменения, это будет работать,

    double Sum(std::list<int>::const_iterator Start, std::list<int>::const_iterator End)
{
double sum=0;
for (Start;Start!=End;Start)
sum+=*(--Start);
return sum;
}
-2

По вопросам рекламы [email protected]