Векторные итераторы <or! =

Может ли кто-нибудь помочь мне понять, есть ли большая разница в != И < когда речь заходит о векторных итераторах в цикле for?

Я имею в виду, независимо от того, используете ли вы != И <, результат должен быть таким же?

for (vector<int>::iterator i = vec.begin(); i != vec.end(); i++)
    // DO STUFF
for (vector<int>::iterator i = vec.begin(); i < vec.end(); i++)
    // DO STUFF

Я знаю, что наиболее распространенным способом является использование !=, Но будет ли < большая проблема при использовании?

Ответы

Ответ 1

operator< поддерживается только для итераторов произвольного доступа. std::vector::iterator - это std::vector::iterator с произвольным доступом, поэтому оба i != vec.end() и i < vec.end() поддерживаются и действительны и не имеют никакого значения в вашем примере.

Если у вас есть контейнер, который не поддерживает итераторы с произвольным доступом (например, std::list), i < list.end() не будет компилироваться.

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

Кроме того, если цикл вызывает функцию, определение которой недоступно в этом модуле трансляции, vec.end() будет перезагружаться из памяти на каждой итерации цикла, что может привести к ненужной ошибке кеша. Вы можете избежать перезагрузки, сохранив значение в локальной переменной, чтобы компилятор был уверен, что локальная переменная недоступна для любой другой функции:

for(vector<int>::iterator i = vec.begin(), j = vec.end(); i < j; ++i)
    // ...

Еще лучше, вы можете использовать циклы диапазона, которые избегают этих ошибок производительности для вас:

for(auto const& elem : vec)
    // ...

Ответ 2

Вся философия, стоящая за частью STL стандартной библиотеки (контейнеры, итераторы и алгоритмы), заключается в минимизации программных различий между контейнерами. Они демонстрируют разные свойства, но как вы их программируете, должны быть как можно более похожими.

Это упрощает обучение и упрощает использование в целом. Это означает, что вы можете написать одну общую функцию (или алгоритм) и применить ее к любому другому контейнеру (или как можно больше).

Имея это в виду, полезно использовать синтаксис, который является общим для всех контейнеров и итераторов, где это возможно.

Только итераторы некоторых контейнеров позволяют принимать итераторы < сравнения, но все контейнеры !=. По этой причине я бы рекомендовал всегда использовать != качестве последовательности и облегчить перенос кода в другой контейнер.

Ответ 3

Это имеет значение, хотя и не для std::vector. Все итераторы равны друг другу, поэтому != Всегда будет работать. Итераторы с произвольным доступом менее сопоставимы, как и std::vector, поэтому в вашем случае это не будет большой проблемой.