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_iterators, 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.