c – Boost Variant:如何建模JSON?

我正在尝试使用Boost Spirit商店 JSON对象将 JSON字符串解析为递归数据结构:
Value <== [null,bool,long,double,std::string,Array,Object];
Array <== [Value,Value,...];
Object <== ["name1": Value,"name2": Value,...];

这是我的代码

#include <map>
#include <vector>
#include <string>
#include <boost/variant.hpp>
#include <boost/shared_array.hpp>
#include <boost/shared_ptr.hpp>

struct JsonNull {};
struct JsonValue;

typedef std::map<std::string,JsonValue *> JsonObject;
typedef std::vector<JsonValue *> JsonArray;

struct JsonValue : boost::variant<JsonNull,JsonArray,JsonObject>
{
};

JsonValue aval = JsonObject();

编译时我得到错误

Error C2440: 'initializing' : cannot convert from 'std::map<_Kty,_Ty>' to 'JsonValue'

而且,如何安全地将JsonValue转换为JsonObject?当我尝试做:

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

这会导致运行时异常/致命故障.

任何帮助是极大的赞赏.

编辑:

按照@ Nicol的建议,我推出了以下代码

struct JsonNull {};
struct JsonValue;

typedef std::map<std::string,JsonValue *> JsonObject;
typedef std::vector<JsonValue *> JsonArray;
typedef boost::variant<
    JsonNull,JsonObject,boost::recursive_wrapper<JsonValue>
> JsonDataValue;

struct JsonValue
{
    JsonDataValue data;
};

我可以在JsonObject& JsonArray就像这样简单:

JsonValue *pJsonVal = new JsonValue();

boost::get<JsonObject>(pCurrVal->data).insert(
    std::pair<std::string,JsonValue *>("key",pJsonVal)
);

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

只是张贴,以便每个人都可以从中受益.

解决方法

你必须使用递归包装器(你不应该从boost :: variant派生):
struct JsonValue;

typedef boost::variant</*types*/,boost::recursive_wrapper<JsonValue> > JsonDataValue;

struct JsonValue
{
    JsonDataValue value;
};

要使Boost.Spirit采用JsonValue,您需要编写其中一个Fusion适配器以使原始变体类型适应结构.

Moreover,how to safely cast JsonValue to JsonObject? When I try doing:

这不是变体的工作方式.如果要将它们设置为值,只需将它们设置为任何其他值:

JsonValue val;
val.value = JsonValue();

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...