9
votes

C ++: Comment écrire un const_iterator?

J'ai écrit mon propre modèle de conteneur avec un itérateur. Comment puis-je implémenter const_iterator? XXX


0 commentaires

3 Réponses :


4
votes

La seule différence doit être que lorsque vous référendez un itérateur Const, vous obtenez une référence constante plutôt qu'une référence à l'objet dans le conteneur.


4 commentaires

Qu'en est-il des méthodes qui empruntent les itérateurs comme des arguments ou renvoient des itérateurs? Je dois les surcharger pour Const_iterators? Semble être un tas de code répété.


Les itérateurs doivent être convertibles en const_itées, de sorte que vous n'aurez pas à surcharger si vous n'avez besoin que d'un const_iterator. Vous faites pour des fonctions telles que Begin (), Fin (), mais il n'y a aucun moyen de cela, comme il fait également partie de la signature de la méthode.


@ Posco Grubb: Non. Si vous avez des méthodes qui prennent des itérateurs, alors les modèles. La méthode devrait fonctionner pour tout ce qui agit comme un itérateur. Si la méthode nécessite un itérateur plutôt qu'un const_iterator, le compilateur générera l'erreur appropriée.


Aussi, ajoutez un constructeur de conversion modélisé en const_iterator qui prend un itérateur. Ensuite, vous pouvez convertir commodément d'un non-const à un const_iterator.



2
votes

Je trouve le moyen le plus simple de mettre en œuvre des itérateurs est Boost :: Itérateur . Si vous voulez rouler le vôtre, je pense que la signature doit être la suivante: xxx

avec la mise en oeuvre de la même manière (en supposant que vous utilisez référence_type et ainsi de suite dans vos signatures de fonction) < / p>


6 commentaires

J'ai été surpris de trouver que itérator_traits :: const_iterator> :: valeur_type est int, pas int const (t, au lieu de const T dans votre code). Je pense que avec const fait plus de sens cependant. Cependant, la première ligne est si vous souhaitez correspondre aux conteneurs standard, vous devez utiliser Non-Const T.


La chose importante avec un itérateur constant est que vous ne pouvez pas l'utiliser pour changer la collection itératée sur. Alors, t ou const t & est approprié. Utiliser Cons avec Just t n'est pas nécessaire (puisque le retour sera une copie)


Eh bien, si vous souhaitez spécifier que la valeur par valeur est non-const, vous devez spécifier tous les paramètres: Class Const_iterator: Public STD :: Itérateur . J'irais avec brièveté (avec une certaine protection contre les bogues d'assignation / égalité) plutôt que de la conformité avec le vecteur stl, mais c'est un choix difficile d'un point de vue de la conception.


Je préférerais également une non-const T. de sorte que les fonctions qui renvoient value_type renvoient une personne non constituée (donc les constructeurs de déplacement pourraient être écrits et efficaces). En outre, les compilateurs pourraient avertir si une telle fonction comme Iter :: value_type f (ITER B, ITER E); est généré (il n'y a pas de figuier de type non de classe).


Hm wow. Beaucoup de choses que je n'avais pas envisagées. Ce que je voulais, c'est un itérateur de telle sorte que la valeur (t) ne puisse pas être modifiée lorsque le conteneur est itérisé sur (my_container) peut être modifié. Je souhaitais également la compatibilité avec STL, mais si je comprends les commentaires ci-dessus correctement, un const_iteratorateur STL est le contraire: il permet de modifier l'objet contenu et de désactiver la modification du conteneur.


Non, la STL n'autorise pas le conteneur ou ses valeurs à modifier via un itérateur Const (Constance logique), comme référence_TYPE (utilisé pour passer par référence) de const_iterator Typefed à une référence à la const. La discussion ci-dessus concerne Value_Type (utilisée pour réussir par la valeur) et si pour le conteneur Value_Type de const_iterator était typé à t, ou const T. J'avais supposé ce dernier, ce qui était incorrect.



0
votes

Roger Pate, Value_Types sont "simples". Je soupçonne que vous verrez le const si vous regardez iterator_traits :: const_iterator> :: Référence, que je pense être "const int &".


0 commentaires