您没有列出诸如 之类的类型bar
,所以我仅Bar
用于该类型。
你可以给自己一些辅助方法,利用状态码或异常,这取决于你期望失败的常见程度。
bool get_string(std::string& result, const Bar& bar, const char* name)
{
if(bar.isMember(name) && bar[name].isString())
{
result = bar[name].asString();
return true;
}
return false;
}
// and similarly
bool get_int(int& result, const Bar& bar, const char* name)
{
if(bar.isMember(name) && bar[name].isInt())
{
result = bar[name].asInt();
return true;
}
return false;
}
然后你可以使用它:
JSON::Value bar;
std::string baz;
int buzz;
if(get_object(bar, root, "bar"))
{
if (get_string(baz, bar, "baz")
&& get_int(buzz, bar, "buzz"))
{
// do things with baz and buzz
}
else{ err["bar"] = argument_error; }
}
这稍微干净一些,但不是突飞猛进。如果您期望您正在寻找的东西存在,并且不太可能出现故障,那么我们可以使用异常。我们也可以用模板全力以赴:
// set up template forms to check types
template<typename T> bool is_a(const Bar& b);
template<> bool is_a<std::string>(const Bar& b) { return b.isString(); }
template<> bool is_a<int> (const Bar& b) { return b.isInt(); }
template<> bool is_a<JSON::Value>(const Bar& b) { return b.isObject(); }
// templates to extract as a type
template<typename T> T as_type(const Bar& b);
template<> std::string as_type<std::string>(const Bar& b) { return b.asString(); }
template<> int as_type<int> (const Bar& b) { return b.asInt(); }
template<> JSON::Value as_type<JSON::Value>(const Bar& b) { return b.asObject(); }
// the one extraction method
template<typename T>
T get(const Bar& bar, const char* name)
{
if ( ! bar.isMember(name)) throw std::runtime_error("not a member");
if ( ! is_a<T>(bar[name])) throw std::runtime_error("wrong type");
return as_type<T>(bar[name]);
}
// and now we use it
try
{
JSON::Value bar = get<JSON::Value>(root, "bar");
std::string baz = get<std::string>(bar, "baz");
int buzz = get<int>(bar, "buzz");
// do things with baz and buzz
}
catch (const std::runtime_error& exc)
{
err["bar"] = argument_error;
}
设置需要更多方法,但现在使用它非常简单和干净。