7 votes

Booster Variant: Comment modéliser JSON?

Je tente d'analyser une chaîne JSON en utilisant Boost Spirit pour stocker l'objet JSON dans des structures de données récursives :

Value <== [null, bool, long, double, std::string, Array, Object];
Array <== [Value, Value, Value, ...];
Object <== ["nom1": Value, "nom2": Value, ...];

Et voici mon code :

#include 
#include 
#include 
#include 
#include 
#include 

struct JsonNull {};
struct JsonValue;

typedef std::map JsonObject;
typedef std::vector JsonArray;

struct JsonValue : boost::variant
{
};

JsonValue aval = JsonObject();

Lors de la compilation, j'obtiens l'erreur :

Erreur C2440 : 'initialisation' : impossible de convertir de 'std::map<_Kty,_Ty>' en 'JsonValue'

De plus, comment convertir en toute sécurité JsonValue en JsonObject ? Lorsque j'essaie :

boost::get(aval) = JsonObject();

Cela génère une exception/échec fatal à l'exécution.

Toute aide est grandement appréciée.

ÉDITER :

Suivant le conseil de @Nicol, j'en arrivé au code suivant :

struct JsonNull {};
struct JsonValue;

typedef std::map JsonObject;
typedef std::vector JsonArray;
typedef boost::variant<
    JsonNull, bool, long, double, std::string,
    JsonObject, JsonArray,
    boost::recursive_wrapper
> JsonDataValue;

struct JsonValue
{
    JsonDataValue data;
};

Je peux travailler sur JsonObject & JsonArray aussi facilement que ceci :

JsonValue *pJsonVal = new JsonValue();

boost::get(pCurrVal->data).insert(
    std::pair("clé", pJsonVal)
);

boost::get(pCurrVal->data).push_back(pJsonVal);

Je poste ceci afin que tout le monde puisse en bénéficier.

6voto

Nicol Bolas Points 133791

Vous devez utiliser un wrapper récursif (et vous ne devriez pas dériver de boost::variant) :

struct JsonValue;

typedef boost::variant> JsonDataValue;

struct JsonValue
{
    JsonDataValue value;
};

Pour que Boost.Spirit prenne un JsonValue, vous devrez écrire un de ces adaptateurs Fusion pour adapter le type de variante brut en une structure.


De plus, comment convertir en toute sécurité JsonValue en JsonObject ? Quand j'essaie de faire :

Ce n'est pas ainsi que les variantes fonctionnent. Si vous voulez les définir à une valeur, définissez-les simplement comme n'importe quelle autre valeur :

JsonValue val;
val.value = JsonValue();

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