13 votes

Sauter l'itérateur

J'ai une séquence de valeurs que j'aimerais passer à une fonction qui prend un paramètre (iterator begin, iterator end) paire. Cependant, je ne veux traiter qu'un élément sur deux dans la séquence originale.

Existe-t-il un moyen simple d'utiliser Standard-Lib/Boost pour créer une façade d'itérateur qui me permette de passer dans la séquence originale ? Je pensais que quelque chose de simple comme ça serait déjà dans les bibliothèques boost iterators ou range, mais je n'ai rien trouvé.

Ou est-ce que j'oublie un autre moyen tout à fait évident de le faire ? Bien sûr, je sais que j'ai toujours la possibilité de copier les valeurs dans une autre séquence, mais ce n'est pas ce que je veux faire.

Edita: Je connais filter_iterator mais cela permet de filtrer les valeurs - cela ne change pas la façon dont l'itération progresse.

6voto

Nathan Phillips Points 2849

Je pense que vous voulez boost::adaptors::strided

3voto

Paul Michalik Points 3060
struct TrueOnEven {
 template< typename T >
 bool operator()(const T&) { return mCount++ % 2 == 0; }
 TrueOnEven() : mCount(0) {}
 private:
  int mCount;
};

int main() {
 std::vector< int > tVec, tOtherVec;
 ...
 typedef boost::filter_iterator< TrueOnEven, int > TakeEvenFilterType;

 std::copy( 
  TakeEvenFilterType(tVec.begin(), tVec.end()),
  TakeEvenFilterType(tVec.end(), tVec.end()),
  std::back_inserter(tOtherVec));
}

Pour être honnête, c'est tout sauf agréable et intuitif. J'ai écrit une bibliothèque "Enumerator" simple incluant des requêtes intégrées paresseuses afin d'éviter les problèmes comme ceux décrits ci-dessus. Elle vous permet d'écrire :

Query::From(tVec.begin(), tVec.end())
.Skip<2>()
.ToStlSequence(std::back_inserter(tOtherVec));

Skip<2> instancie en fait un "filtre" généralisé qui saute tous les N-ièmes éléments (dans ce cas, tous les deuxièmes).

2voto

rubenvb Points 27271

Voici le texte de Boost itérateur de filtre . C'est exactement ce que vous voulez.

UPDATE : Désolé, j'ai mal lu. Voici une liste de toutes les bizarreries des itérateurs dans Boost :

http://www.boost.org/doc/libs/1_46_1/libs/iterator/doc/#specialized-adaptors

Je pense qu'un simple adaptateur iterator_adaptor avec une fonction surchargée operator++ qui incrémente deux fois la valeur de l'itérateur sous-jacent est tout ce dont vous avez besoin.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X