#include <iostream>
#include <string>
#include <ranges>
int main()
{
std::string str { "C++ is Cool!" };
std::cout << str << '\n';
// old school for loop
for (size_t i { }; i < str.size(); ++i) { std::cout << str[i] << ' '; }
std::cout << '\n';
// for loop using const iterators
for (auto itr { str.cbegin() }; itr != str.cend(); ++itr) { std::cout << *itr << ' '; }
std::cout << '\n';
// https://en.cppreference.com/w/cpp/language/range-forfor (constchar& itr : str) { std::cout << itr << ' '; }
std::cout << "\n\n";
// old school reverse for loop
for (size_t i { str.size() }; i > 0; --i) { std::cout << str[i - 1] << ' '; }
std::cout << '\n';
// reverse for loop with const iterators
for (auto itr { str.crbegin() }; itr != str.crend(); ++itr) { std::cout << *itr << ' '; }
std::cout << '\n';
// https://www.fluentcpp.com/2020/02/11/reverse-for-loops-in-cpp/for (constchar& itr : str | std::views::reverse) { std::cout << itr << ' '; }
std::cout << "\n\n";
// range-based for loops work with regular arrays as well
int arr[] { 5, 10, 15, 20, 25 };
for (constint& itr : arr) { std::cout << itr << ' '; }
std::cout << '\n';
for (constint& itr : arr | std::views::reverse) { std::cout << itr << ' '; }
std::cout << '\n';
}
C++ is Cool!
C + + i s C o o l !
C + + i s C o o l !
C + + i s C o o l !
! l o o C s i + + C
! l o o C s i + + C
! l o o C s i + + C
5 10 15 20 25
25 20 15 10 5
The value of i that's supposed to cause the loop to terminate, is not generally "reachable" from the prior value of i. This violates the semantic requirements of std::contiguous_iterator.
>> Compile without it and the code works as expected.
The sane option is to avoid undefined behaviour in our code, even if it may appear to "work fine" or "as expected" on a particular implementation (on the occasions when we tried it).
Permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message). https://eel.is/c++draft/intro.defs#defns.undefined