void makeSnaflu(const std::vector<int>& vec) { for(int x : vec) doFooBar(x); }
Unfortunately, a sheer number of STL classes and containers allow iterating in a reverse order using
reverse_iterator
s, but there is no support for them in the range-based for loop.However, this could be fixed easily by creating a proxy template which uses some c++11 features. This template proxy assumes the class provides reverse iterators via
rbegin()
and rend()
, in the same manner that the range-based for loop assumes the object passed provides begin()
and end()
:template<class Cont> class const_reverse_wrapper { const Cont& container; public: const_reverse_wrapper(const Cont& cont) : container(cont){ } decltype(container.rbegin()) begin() const { return container.rbegin(); } decltype(container.rend()) end() const { return container.rend(); } }; template<class Cont> class reverse_wrapper { Cont& container; public: reverse_wrapper(Cont& cont) : container(cont){ } decltype(container.rbegin()) begin() { return container.rbegin(); } decltype(container.rend()) end() { return container.rend(); } }; template<class Cont> const_reverse_wrapper<Cont> reverse(const Cont& cont) { return const_reverse_wrapper<Cont>(cont); } template<class Cont> reverse_wrapper<Cont> reverse(Cont& cont) { return reverse_wrapper<Cont>(cont); }
Here
decltype()
is super handy when it comes to allow the rbegin()
and rend()
to return pretty much anything they like.Now you can easily iterate to string in a reverse order:
std::string stressed = "stressed no tips"; for(char c : reverse(stressed)) std::cout << c; std::cout << std::endl;
You may want to follow me on twitter.