arborescence des propriétés put / erase avec const iterator, ou comment convertir const_iterator en iterator

J’utilise boost 1.55.0 sur Ubuntu 12.04lts avec Clang 3.4.

J’ai un boost::property_tree::ptree dont l’entrée xml ressemble à:

    dad 43   me 4    

J’ai donc une liste de nœuds avec la même balise.

Pour les lire, je parcours l’arborescence et, en fonction d’une condition, je veux effacer un nœud. Cela ressemble à:

 boost::property_tree::ptree pt; boost::property_tree::read_xml(inputFileName, pt); boost::property_tree::ptree& persons = pt.get_child("root"); for(boost::property_tree::ptree::const_iterator it = persons.begin(); it != persons.end(); ++it) { std::ssortingng name = it->second.get("name"); if(name == "dad") // erase that name node from pt persons.erase(it->second.find("name"); // this doesn't work } 

[ Edit ] Comme le suppose la réponse de pmr, j’ai écrit le code suivant:

 boost::property_tree::ptree::iterator i = persons.begin(); auto assoc_i = it->second.find("name"); auto ci = persons.to_iterator(assoc_i); std::advance(i, std::distance(iterator, ci)); // --> here it hangs persons.erase(i); 

Maintenant, il comstack, et l’application ne plante pas, mais elle se bloque à la position mentionnée. Et je ne sais pas pourquoi. [ / Edit ]

Merci d’avance.

Votre problème n’a rien à voir avec la constance des iterators, vous effacez simplement avec le mauvais iterator.

 ptree& persons = pt.get_child("root.persons"); for(auto it = persons.begin(); it != persons.end();) { if(it->second.get("name") == "dad") it = persons.erase(it); else ++it; } 

Ptree utilise un multi_index pour les sous-nœuds et pour maintenir une itération stable sur les effacements, vous devez utiliser l’iterator renvoyé par l’opération erase () pour poursuivre l’itération, un modèle commun.

Notez que la terminaison / ( ) est manquante dans le XML de la question, elle ne serait pas validée. Je ne modifie pas la question pour la résoudre car cela pourrait être l’un des problèmes que vous rencontrez avec l’exécution du programme.

Sortie du traitement du ptree avec le code ci-dessus via write_xml(std::out, pt) :

     me 4    

Les API C ++ 11 pour les conteneurs spécifient un iterator container::erase(const_iterator, const_iterator) fonction membre iterator container::erase(const_iterator, const_iterator) . Malheureusement, basic_ptree ne le fait pas, vous êtes donc coincé avec l’ancienne méthode C ++ de conversion d’un const_iterator en iterator :

 // tree is your ptree, my_const_iter a ptree::const_iterator ptree::iterator i = tree.begin(); advance (i, std::distance(i,my_const_iter));