A simple force multiplier that should be in every C++11-and-later programmer’s toolbox:

template<class It> struct iterator_range { It begin_, end_; constexpr It begin() const noexcept { return begin_; } constexpr It end() const noexcept { return end_; } }; template<class It> constexpr auto make_range(It first, It last) noexcept { return iterator_range<It>(first, last); }

This lets us do

char *data = "hello world"; for (char elt : make_range(data+4, data+8)) { putchar(elt); }

(Yes, yes, CTAD lets us say iterator_range instead of make_range if we don’t need portability to C++14. Please raise your hand if that’s your situation.)

Also for your toolbox:

template<class Ctr> constexpr auto reversed(Ctr&& c) noexcept { return make_range(c.rbegin(), c.rend()); }

This lets us do

std::string data = "hello world"; for (char elt : reversed(data)) { putchar(elt); }

or by combining the two

char *data = "hello world"; for (char elt : reversed(make_range(data+4, data+8))) { putchar(elt); }

Adding convenience overloads of reversed(first, last) , adding fallbacks in terms of std::make_reverse_iterator(first) , etc., are all left as an exercise for the reader.