Ваш код содержит некоторое неопределенное поведение. Как вы уже указали, S будет содержать все значения от 0 до 20 (эксклюзивные), хотя как-то печать дает 1 до 20 (включительно).
Ваш код:
for(auto it = S.end();it!=S.begin();--it)
cout<<*it<<" ";
Проблема здесь состоит в том, что диапазон [begin, end)
имеет end
ссылаясь на то, что не является частью набора. Разыменование итератора, полученного от end(), может привести к сбою вашей программы или дать произвольное случайное значение. В этом случае, я думаю, вы получаете значение 20 из-за оптимизации компилятора. (Некоторая оптимизация черного ящика)
В C++ (и других языках) понятие итераторов сопровождается концепцией reverse iterators. (Если вы по ссылке, есть хорошая картина объяснения итераторы.)
В основном, при помощи обратного итераторы позволит вам петлю от задней части к началу, как если бы вы были зацикливание с нормальными итераторов:
for (auto it = S.crbegin(); it != S.crend(); ++it)
cout << *it << " ";
Обратите внимание, что функции rbegin() и crbegin() не имеют недостатков в сложности кода. (если вы не хотите снова преобразовать их в передний итератор)
Бонус: По умолчанию, не используйте оператор -оператор на итераторах, он дает головные боли при попытке отладки.
Это, по-видимому, правильный выход, данный вашей программе. – Chad
Он ведет себя правильно. Чего ты ожидал? (Проблема XY ???) – MTilsted
Что вы ожидаете? – Harald