11
votes

Faire ma classe C ++ iTérable via boost_foreach

J'ai une classe que je veux exposer une liste de structures (qui contiennent simplement des entiers). Je ne veux pas que l'extérieur modifie ces données, je suffisez-vous et les lisez Exemple: xxx

maintenant dans mon code, je veux utiliser ma classe comme ceci: xxx

J'ai déjà lu cet article http://accu.org/index.php/journals/1527 sur les objets. Cependant, je ne veux pas (ou ne pouvez pas) sauvegarder tous les TestData dans un vecteur interne ou quelque chose. En effet, la classe elle-même ne possède pas le stockage, c'est-à-dire qu'aucun conteneur sous-jacent ne peut être accessible directement par la classe. La classe elle-même peut interroger un composant externe pour obtenir le prochain, précédent ou ith élément, cependant.

Donc, je veux que ma classe se comporte comme si elle avait une collection, mais elle n'a pas une. Des idées?


5 commentaires

Vous n'avez que vous devez simplement fournir des fonctions de début / de fin de retour des itérateurs appropriés?


Oui, mais je n'ai pas de conteneur sous-jacent qui pourrait me fournir ces itérateurs


Alors écris-les toi-même. :) La bibliothèque Boost.iterator devrait vous faire monter et courir assez rapidement.


Oui, cela ne devrait pas, mais ce n'est pas ;-) Je ne sais pas vraiment où commencer, il y a tellement de types d'itérateurs différents. Tous les exemples utilisent des conteneurs existants: /


Non, ils ne le font pas. Ils ont un exemple montrant comment écrire des itérateurs pour une liste liée faite sur mesure. La classe de la façade d'itérateur vous demande simplement de mettre en œuvre le Dréréférence () et incrément fonctions, et peut-être un ou deux autres personnes, et vous êtes essentiellement fait. Dans votre cas, l'incrément appellerait probablement la fonction de requête et cache le résultat. Et la déréférence rendrait la valeur mise en cache.


3 Réponses :


0
votes

Si votre type de collection présente une interface de conteneur standard, vous n'avez rien à faire pour faire boost_foreach fonctionner avec votre type. En d'autres termes, si votre type a itérateur et const_iterator TypeDFS imbriqué et commencez () et fin () Fonctions membres, BOOST_FORTACH sait déjà comment itération sur votre type. Aucune autre action n'est requise.

http: //boost-sandbox.sourceforge .NET / LIBS / FORECH / DOC / HTML / BOOST_FORACH / Extending_Boost_Foreach.html


1 commentaires

Je sais à ce sujet, mais où irai-je ces itérateurs? Il n'y a pas de conteneur sous-jacent dont je pouvais utiliser les itérateurs



5
votes

Il semble que vous devez écrire vos propres itérateurs.

La bibliothèque Boost.Iterator a un certain nombre de modèles utiles. Je l'ai utilisé leur classe de base Façade Iterator une ou deux fois, et il est agréable et facile de définir vos propres itérateurs l'utiliser.

Mais même sans elle, itérateurs ne sont pas la science des fusées. Ils ont juste d'exposer les opérateurs à droite et typedefs. Dans votre cas, ils vont juste être wrappers autour de la fonction de requête qu'ils doivent appeler quand ils sont incrémentés.

Une fois que vous avez défini une classe iterator, il vous suffit d'ajouter begin () et end () Fonctions membres à votre classe.

On dirait que l'idée de base va devoir être d'appeler votre fonction de requête lorsque l'itérateur est incrémenté, pour obtenir la valeur suivante. Et déréférencer doit alors retourner la valeur récupérée du dernier appel de la requête.

Il peut aider à jeter un oeil à la bibliothèque standard stream_iterator s pour certains de la sémantique, car ils ont aussi le travail autour de certains fishy « nous n'avons pas vraiment un conteneur, et nous ne peut pas créer itérateurs pointant ailleurs que dans la position de flux en cours » questions.

Par exemple, en supposant besoin d'appeler un query () qui retourne NULL lorsque vous avez atteint la fin de la séquence, la création d'une « fin iterator » va être difficile. Mais vraiment, tout ce que vous avez besoin est de définir l'égalité de sorte que « itérateurs sont égaux si les deux NULL magasin comme leur valeur en cache ». Alors initialiser la "fin" iterator avec NULL.

Il peut aider à rechercher la sémantique requises pour itérateurs d'entrée, ou si vous lisez la documentation Boost.Iterator, pour itérateurs un seul passage spécifique. Vous ne serez probablement pas en mesure de créer multipass itérateurs. Alors regardez exactement ce comportement est requis pour un seul passage iterator et bâton à cela.


1 commentaires

Et parce que je suis un gars sympa: entrée Itérateur concept >> SGI.com/tech/ STL / INTERTITHERATOR.HTML



0
votes

de la page de documentation de Boost For_each:

boost_foreach iTerate sur des séquences. Mais qu'est-ce qui se qualifie comme une séquence, exactement? Puisque Boost_Foreach est construit sur Boost.Range, il prend en charge automatiquement ces types qui boost.Range reconnaît comme des séquences. Spécifiquement, BoostT_Foreach fonctionne avec des types qui satisfont au concept de plage de points de passage unique. Par exemple, nous pouvons utiliser boost_foreach avec:


0 commentaires