IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SL & STL C++ Discussion :

[map] constance des itérateurs à l'insertion


Sujet :

SL & STL C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut [map] constance des itérateurs à l'insertion
    Salut,

    Je me posais la question de savoir si les itérateurs dans les maps, principalement, mais cela pourrait être généralisé à l'ensemble des conteneurs, restaient constant lors d'une insertion.

    Il se fait que j'ai plusieurs classes qui devraient faire référence à une (et parfois même, à plusieurs) éléments qui se trouvent dans des conteneurs de la STL, et l'une des solutions envisageables seraient, tout simplement, de déclarer un membre comme étant un itérateur de la map dans laquelle apparait cet élément (étant entendu que les éléments présents dans le conteneur ne seront jamais retirés).

    La question est donc:
    si je défini un membre comme étant un itérateur sur l'élément correspondant dans la map et que, par la suite, la map subit une insertion, l'itérateur précédemment défini restera-t-il valide et correct, ou risque-t-il de subir une modification quelconque (pointer vers un autre élément ou, carrément, pointer sur un endroit invalide)
    Merci d'avance
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  2. #2
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    La réponse dépend du conteneur. Pour une map, c'est bon, le seul point étant la suppression qui invalide l'itérateur de l'élément supprimé.

    Pour un vecteur, n'importe quelle insertion invalide les itérateurs sauf si un bon reserve a été fait avant, et une suppression invalide les itérateurs arrivant après l'élément supprimé.

    Pour une liste, même principe qu'une map.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Pour une map, c'est bon, le seul point étant la suppression qui invalide l'itérateur de l'élément supprimé.
    Mais le seul itérateur invalidé serait donc l'élément supprimé

    Si oui, cela signifie qu'il n'y aurait que les instances qui utilisent cet itérateur bien précis qui deviendraient invalides...

    A l'extrème limite, en passant par un DP proche de l'observer, on pourrait alors veiller à ce que les instances concernées soient correctement détruites
    Citation Envoyé par JolyLoic
    Pour un vecteur, n'importe quelle insertion invalide les itérateurs sauf si un bon reserve a été fait avant, et une suppression invalide les itérateurs arrivant après l'élément supprimé.
    je m'en serais douté, du fait des réallocations qui risquent de survenir à l'insertion...

    Si je devais utiliser un vecteur, j'utiliserais plutot comme référence simplement... l'index dans le tableau, en interdisant l'ajout ailleurs qu'en fin de tableau

    Encore une fois, tu te montres digne de ta réputation
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Membre émérite
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Mais le seul itérateur invalidé serait donc l'élément supprimé

    Si oui, cela signifie qu'il n'y aurait que les instances qui utilisent cet itérateur bien précis qui deviendraient invalides...
    Je serais partisant de dire que seul l'itérateur pointant sur l'élément supprimé serait invalide : je ne pense pas qu'à chaque insertion la map réorganise sa mémoire.
    Un moyen simple de vérifier serait de tester avec deux itérateurs : un sur l'entrée que tu veux supprimer, l'autre sur l'entrée qui suit.
    Comme erase te renvoie un itérateur sur l'élément qui suit directement celui qui vient dêtre supprimé, tu n'as qu'à vérifier si ce retour est égal à celui qui tu avais sauvegardé.

    Je sais pas si j'ai été très clair...

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    [QUOTE=spoutspout;2670956]<snip>
    Comme erase te renvoie un itérateur sur l'élément qui suit directement celui qui vient dêtre supprimé, tu n'as qu'à vérifier si ce retour est égal à celui qui tu avais sauvegardé./QUOTE]

    Ah, non... la méthode erase d'une map renvoie, au mieux, le nombre d'éléments supprimés, et encore, à condition d'utiliser la synthaxe eras(iterator first, iterator last), qui est de type size_t... Et vouloir utiliser ce retour comme base de définition d'un itérateur (par exemple, en utilisant le nombre comme la clé de la map) revient à s'élancer vers un mur

    Quoi qu'il en soit, cette "question subsidiaire" avait plus pour but de m'assurer de la bonne compréhension des écrits de JolyLoic, car, comme je l'ai signalé, il ne devrait normalement pas y avoir de suppression dans les map utilisées (mais bon, quelques tests seront peut être tentés, si besoin est)...

    Bien plus que la suppression, c'était surtout le comportement des itérateurs lors de l'insertion qui m'intéressaient (m'inquiétaient )

    @JolyLoic: merci de cette précision
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre émérite
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Ah, non... la méthode erase d'une map renvoie, au mieux, le nombre d'éléments supprimés, et encore, à condition d'utiliser la synthaxe erase(iterator first, iterator last), qui est de type size_t...
    Euh, je suis pas d'accord, à moins qu'on parle pas de la même chose! Moi j'ai ça comme doc.

  7. #7
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Mais le seul itérateur invalidé serait donc l'élément supprimé
    Oui
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  8. #8
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    La réponse dépend du conteneur. Pour une map, c'est bon, le seul point étant la suppression qui invalide l'itérateur de l'élément supprimé.

    Pour une liste, même principe qu'une map.
    Pour une liste ok (et encore...), Mais pour la map (comme tout contener associatif), cela ne va pas dépendre de son implémentation?
    Par exemple, une map pourrai bien être un vector sous forme de heap où le tri se fait en fonction de la clef.
    non?

  9. #9
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Mongaulois Voir le message
    Pour une liste ok (et encore...), Mais pour la map (comme tout contener associatif), cela ne va pas dépendre de son implémentation?
    Par exemple, une map pourrai bien être un vector sous forme de heap où le tri se fait en fonction de la clef.
    non?
    Pourquoi, dans le sens où la clé reste fortement liée à... la valeur...

    Si la clé suit correctement les déplacements de la valeur à laquelle elle est associée, pourquoi l'itérateur ne pourrait pas rester "constant" au même titre que si on avait affaire à une liste
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  10. #10
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Pourquoi, dans le sens où la clé reste fortement liée à... la valeur...

    Si la clé suit correctement les déplacements de la valeur à laquelle elle est associée, pourquoi l'itérateur ne pourrait pas rester "constant" au même titre que si on avait affaire à une liste
    Dans le cas que je donne, l'iterateur correspondrai a un endroit du vecteur et lorsqu'il y as une suppression ou un ajout, il se peut que l'endroit pointer par l'iterateur ai changé et il est donc invalidé

  11. #11
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Mongaulois Voir le message
    Dans le cas que je donne, l'iterateur correspondrai a un endroit du vecteur et lorsqu'il y as une suppression ou un ajout, il se peut que l'endroit pointer par l'iterateur ai changé et il est donc invalidé
    Outre que JolyLoic a donné les raisons qui font que, il faut bien penser au fait qu'un tableau associatif travaille réellement sur deux valeurs distinctes: la clé (qui sert pour le tri) et la valeur associée (quel qu'en soit le type)...

    L'itérateur d'un tableau associatif est géré sur base... de la clé

    Le seul cas dans lequel l'itérateur serait invalidé "parce qu'on a retiré un élément dans le tableau de valeurs" serait la conséquence du fait... que l'association clé/valeur a changé... ce qui est pour le moins contraire à l'idée que l'on se fait d'un tableau associatif, non
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  12. #12
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par Mongaulois Voir le message
    Par exemple, une map pourrai bien être un vector sous forme de heap où le tri se fait en fonction de la clef.
    non?
    On pourrait peut-être faire un conteneur semblable à une map ainsi, mais ce ne serait pas un std::map. Dans la définition d'un std::map, il y a plusieurs niveaux :
    - une spécification de l'interface fournie par ce template (le .h en gros) ;
    - une spécification d'ordre plus sémantique (quelle opération invalide un itérateur, en particulier, mais aussi les effet d'un insert sur size, par exemple) ;
    - des contraintes d'algorithmique (l'insertion est en O(log n)).

    Une std::map doit respecter les trois niveaux.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  13. #13
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    - une spécification d'ordre plus sémantique (quelle opération invalide un itérateur, en particulier, mais aussi les effet d'un insert sur size, par exemple) ;
    C'est dans ses spec??? alors c'est cool
    Tu serait ou il y aurait un site qui explique cela?? j'ai pas trouvé

  14. #14
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Je lis directement la norme.
    http://cpp.developpez.com/faq/cpp/?p...tenir_standard

    (Message à un gestionnaire de la FAQ qui passerait dans le coin : Il pourrait être pas mal d'ajouter un lien vers le draft de C++0x sur cette page, non ?)


    Elle ne décrit pas forcément les opérations qui conservent, mais elle décrit toutes les opérations qui invalident. Par exemple :
    Citation Envoyé par La norme §23.1.2.8
    [Associative containers]
    The insert members shall not affect the validity of iterators and references to the container, and the erase
    members shall invalidate only iterators and references to the erased elements.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

Discussions similaires

  1. [hibernate 3] [mapping] Description des clés étrangères
    Par CharlSka dans le forum Hibernate
    Réponses: 2
    Dernier message: 01/02/2007, 09h01
  2. Réponses: 3
    Dernier message: 20/09/2006, 22h35
  3. Petite question a propos des itérateurs
    Par Thordax dans le forum C++
    Réponses: 32
    Dernier message: 06/07/2006, 01h45
  4. Réponses: 6
    Dernier message: 09/06/2006, 12h17
  5. [Image] image map dans des images dynamique?
    Par xtaze dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 19/05/2006, 17h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo