69 votes

Pourquoi le fichier write_json de l'arbre de propriétés Boost enregistre-t-il tout sous forme de chaîne de caractères ? Est-il possible de changer cela ?

J'essaie de sérialiser en utilisant l'arbre de propriété write_json de boost, il enregistre tout comme des chaînes, ce n'est pas que les données sont mauvaises, mais je dois les couler explicitement à chaque fois et je veux les utiliser ailleurs. (comme dans python ou une autre bibliothèque C++ json (non boost))

Voici un exemple de code et ce que j'obtiens en fonction de la locale :

boost::property_tree::ptree root, arr, elem1, elem2;
elem1.put<int>("key0", 0);
elem1.put<bool>("key1", true);
elem2.put<float>("key2", 2.2f);
elem2.put<double>("key3", 3.3);
arr.push_back( std::make_pair("", elem1) );
arr.push_back( std::make_pair("", elem2) );
root.put_child("path1.path2", arr);

std::stringstream ss;
write_json(ss, root);
std::string my_string_to_send_somewhare_else = ss.str();

et my_string_to_send_somewhere_else c'est quelque chose comme ça :

{
    "path1" :
    {
       "path2" :
       [
            {
                 "key0" : "0",
                 "key1" : "true"
            },
            {
                 "key2" : "2.2",
                 "key3" : "3.3"
            }
       ]
    }
}

Existe-t-il un moyen de les sauvegarder en tant que valeurs, par exemple : "key1" : true o "key2" : 2.2 ?

2voto

Sean Kinsey Points 17117

À partir de la sortie JSON, il est clair que le sérialiseur transforme tout en chaînes de caractères en utilisant une sorte de méthode .toString() - c'est-à-dire qu'il ne connaît pas le type de chaque membre et enferme donc tout dans " ".

Véase Création de tableaux JSON dans Boost à l'aide de Property Trees pour en savoir plus sur ce problème.

1voto

Secundi Points 804

Toutes les solutions qui requièrent des traducteurs personnalisés pour les chaînes de caractères de manière explicite, semblent être assez sujettes à des erreurs pour moi, car il est probable que je les oublie parfois. Ce serait bien d'avoir une sorte de surcharge via l'héritage pour la méthode put de l'arbre de propriété pour gérer cela implicitement mais ce n'est pas possible de manière robuste puisqu'il s'agit d'un modèle et qu'il faudrait assurer une covariance complète pour toutes les méthodes de l'arbre. En outre, il faut éviter de modifier les éléments de la bibliothèque Boost pour contourner le problème, dans la mesure du possible.

La méthode la plus robuste sans bidouillage que j'ai trouvée jusqu'à présent est (depuis C++11) :

  • utiliser un arbre de propriétés boost avec <KeyType, std::variant<yourTypes>>
  • Fournissez un traducteur pour votre variante (voir le lien ci-dessous pour plus de détails !) mais ne "hackez" pas le contenu en termes de spécificités JSON ! Ce sont des aspects presque totalement orthogonaux !
  • Écrire un lecteur et un rédacteur pour JSON, qui devrait être facilement adapté à partir de ceux de Boost

Pour :

  • aucun bidouillage n'est nécessaire pour affecter l'arbre des propriétés en termes de détails spécifiques à JSON
  • pas de pollution des bibliothèques Boost et de leurs espaces de noms sauf les spécialisations de vos nouveaux types propres (le traducteur de variantes)
  • plus sûr que l'approche de l'arbre de propriété basé sur une chaîne personnalisée
  • devrait être plus rapide pour de nombreux scénarios d'exécution avec une sérialisation non fréquente de l'arbre.

Cons :

  • demande quelques efforts pour un tout petit détail du comportement
  • pourrait être un peu plus lent en termes de compilation.
  • pourrait être un peu plus lent pour les scénarios d'exécution avec sérialisation fréquente et changements mineurs de l'arbre (peut être optimisé pour sûr)
  • la relecture du json dans l'arbre est une sorte de travail philosophique dans le doute pour assurer autant de symétrie que possible entre les types utilisés (pour beaucoup de buts plutôt une question académique)

Pour plus de détails, voir par exemple

http://marko-editor.com/articles/property_tree_store_anything/

Vous pouvez facilement l'adapter à d'autres usages.

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