template<class It>
std::reverse_iterator<It> reversed( It it ) {
return std::reverse_iterator<It>(std::forward<It>(it));
}
Ensuite :
for( auto rit = reversed(data.end()); rit != reversed(data.begin()); ++rit ) {
std::cout << *rit;
Alternativement, en C++14, il suffit de faire :
for( auto rit = std::rbegin(data); rit != std::rend(data); ++rit ) {
std::cout << *rit;
En C++03/11, la plupart des conteneurs standard ont une fonction .rbegin()
y .rend()
également.
Enfin, vous pouvez écrire l'adaptateur de gamme backwards
comme suit :
namespace adl_aux {
using std::begin; using std::end;
template<class C>
decltype( begin( std::declval<C>() ) ) adl_begin( C&& c ) {
return begin(std::forward<C>(c));
}
template<class C>
decltype( end( std::declval<C>() ) ) adl_end( C&& c ) {
return end(std::forward<C>(c));
}
}
template<class It>
struct simple_range {
It b_, e_;
simple_range():b_(),e_(){}
It begin() const { return b_; }
It end() const { return e_; }
simple_range( It b, It e ):b_(b), e_(e) {}
template<class OtherRange>
simple_range( OtherRange&& o ):
simple_range(adl_aux::adl_begin(o), adl_aux::adl_end(o))
{}
// explicit defaults:
simple_range( simple_range const& o ) = default;
simple_range( simple_range && o ) = default;
simple_range& operator=( simple_range const& o ) = default;
simple_range& operator=( simple_range && o ) = default;
};
template<class C>
simple_range< decltype( reversed( adl_aux::adl_begin( std::declval<C&>() ) ) ) >
backwards( C&& c ) {
return { reversed( adl_aux::adl_end(c) ), reversed( adl_aux::adl_begin(c) ) };
}
et maintenant tu peux faire ça :
for (auto&& x : backwards(ctnr))
std::cout << x;
ce que je trouve assez joli.
3 votes
En C++11, vous pouvez utiliser un for-loop basé sur l'intervalle avec un adaptateur inverse, voir ici
1 votes
Théoriquement, sur une machine 32 bits, pour la deuxième solution, si la taille du vecteur est supérieure à 2 147 483 647 + 1, il y aura un débordement (vector::size() est non signé), mais actuellement, il y a de fortes chances que vous n'atteigniez jamais cette limite (la limite actuelle des vecteurs sur les machines 32 bits est également de 1 073 741 823).
2 votes
Le problème de débordement de @StefanRogin devient réel lorsqu'au lieu de "int i" dans la boucle for, quelqu'un utilise size_t (ou peut-être auto) dans sa quête pour éviter les avertissements du compilateur (en raison de l'affectation de size() à int). Avec cela, et pour un vecteur à un seul élément, la deuxième itération déborde auto i et la boucle s'exécute avec le "i" débordé, ce qui entraîne toutes sortes de plantages.