[英]Boost Variant: How to model JSON?
I'm trying to parse JSON string using Boost Spirit store JSON object into recursive data structures:我正在尝试使用 Boost Spirit 存储 JSON object 将 JSON 字符串解析为递归数据结构:
Value <== [null, bool, long, double, std::string, Array, Object];
Array <== [Value, Value, Value, ...];
Object <== ["name1": Value, "name2": Value, ...];
And here's my code:这是我的代码:
#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, bool, long, double, std::string, JsonArray, JsonObject>
{
};
JsonValue aval = JsonObject();
When compiling I get the error:编译时出现错误:
Error C2440: 'initializing' : cannot convert from 'std::map<_Kty,_Ty>' to 'JsonValue'
Moreover, how to safely cast JsonValue to JsonObject?此外,如何安全地将 JsonValue 转换为 JsonObject? When I try doing:
当我尝试这样做时:
boost::get<JsonObject>(aval) = JsonObject();
This gets run-time exception/fatal failure.这会导致运行时异常/致命失败。
Any help is greatly appreciated.任何帮助是极大的赞赏。
Following @Nicol's advice, I came out with the following code:按照@Nicol 的建议,我得出了以下代码:
struct JsonNull {};
struct JsonValue;
typedef std::map<std::string, JsonValue *> JsonObject;
typedef std::vector<JsonValue *> JsonArray;
typedef boost::variant<
JsonNull, bool, long, double, std::string,
JsonObject, JsonArray,
boost::recursive_wrapper<JsonValue>
> JsonDataValue;
struct JsonValue
{
JsonDataValue data;
};
I can work on JsonObject & JsonArray as easy as this:我可以像这样简单地处理 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);
Just posting so that everyone could benefit from this.只是发布,以便每个人都可以从中受益。
You have to use a recursive wrapper (and you shouldn't be deriving from boost::variant
):您必须使用递归包装器(并且您不应该从
boost::variant
派生):
struct JsonValue;
typedef boost::variant</*types*/, boost::recursive_wrapper<JsonValue> > JsonDataValue;
struct JsonValue
{
JsonDataValue value;
};
To make Boost.Spirit take a JsonValue, you will need to write one of those Fusion adaptor things to adapt the raw variant type into a struct.要使 Boost.Spirit 采用 JsonValue,您需要编写其中一个 Fusion 适配器以将原始变体类型调整为结构。
Moreover, how to safely cast JsonValue to JsonObject?
此外,如何安全地将 JsonValue 转换为 JsonObject? When I try doing:
当我尝试这样做时:
That's not how variants work.这不是变体的工作方式。 If you want to set them to a value, just set them like any other value:
如果要将它们设置为一个值,只需像设置任何其他值一样设置它们:
JsonValue val;
val.value = JsonValue();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.