C++ 获取存储在YAML::Node中的YAML cpp值的类型
鉴于此代码:C++ 获取存储在YAML::Node中的YAML cpp值的类型,c++,yaml-cpp,C++,Yaml Cpp,鉴于此代码: void LoadFromYaml(const YAML::Node& node){ const YAML::Node& Data=node["Data"]; if(Data){ if(Data.ValueIsInt)// Do something with integer. if(Data.ValueIsFloat)// Do something with float. if(Data.ValueIs
void LoadFromYaml(const YAML::Node& node){
const YAML::Node& Data=node["Data"];
if(Data){
if(Data.ValueIsInt)// Do something with integer.
if(Data.ValueIsFloat)// Do something with float.
if(Data.ValueIsString)// Do something with string.
}
}
如何检查YAML节点“data”中包含的数据是整数、浮点还是字符串?注意:我不想检查节点是否为标量、映射、序列等。您可以尝试将节点转换为每种类型:
try {
int value = data.as<int>();
// do something
} catch (const BadConversion& e) {
// do something else
}
试试看{
int value=data.as();
//做点什么
}捕获量(常数和e){
//做点别的
}
解析时抛出大量异常会影响解析速度。不确定为什么yamlcpp
没有is_type
方法或类似于std::optional
或std::expected
getter的方法
使用Boost解决这个问题的方法很简单-将您自己的模板专业化注入YAML
名称空间,并返回Boost::optional
(或者std::optional
,如果您有C++17)
名称空间YAML
{
模板
结构如
{
显式as_if(const Node&Node_):Node(Node_){
const节点&Node;
常量boost::可选运算符()()常量
{
boost::可选val;
T;
if(node.m_pNode&&convert::decode(node,t))
val=std::move(t);
返回val;
}
};
//现在已经有一个std::string部分专业化,所以我们需要一个完整的专业化
模板
结构如
{
显式as_if(const Node&Node_):Node(Node_){
const节点&Node;
常量boost::可选运算符()()常量
{
boost::可选val;
std::字符串t;
if(node.m_pNode&&convert::decode(node,t))
val=std::move(t);
返回val;
}
};
}
然后,您可以运行类似于
boost::optional<bool> as_bool = YAML::as_if<bool, boost::optional<bool> >(node)();
boost::optional<int> as_int = YAML::as_if<int, boost::optional<int> >(node)();
boost::optional<double> as_double = YAML::as_if<double, boost::optional<double> >(node)();
boost::optional<std::string> as_string = YAML::as_if<std::string, boost::optional<std::string> >(node)();
boost::可选as_bool=YAML::as_if(node)();
boost::可选的as_int=YAML::as_if(node)();
boost::可选as_double=YAML::as_if(node)();
boost::可选as_string=YAML::as_if(node)();
此处的施工总成本为4个可选值+4个默认值。这可能比处理异常要快,也可能不快,我还没有测试过 谢谢,但是对于这3种类型的try/catch块,有什么好方法可以串联编码呢?还是筑巢是唯一的方法;当有几个是真的时,你必须决定你想要什么样的行为。例如,它总是一个字符串(如果它是标量),如果它是一个int,它也将是一个float。好的,那么测试float,然后int,然后string就可以了。天哪,谢谢你的回答!实际上我忘了我有这个问题。异常非常缓慢,因为它们会展开堆栈,所以我认为您的解决方案非常快。是的,我认为是这样的-像
std::expected
这样的提案的全部基本原理是使这类事情的成功和失败路径具有同等的权重。但是把它放进去了,这样人们就知道做作业了。我已经在一个drop-in.d
风格的YAML解析器中使用了它,因此我们期望在文档外观方面几乎不知道任何信息,因此尽可能避免异常。
boost::optional<bool> as_bool = YAML::as_if<bool, boost::optional<bool> >(node)();
boost::optional<int> as_int = YAML::as_if<int, boost::optional<int> >(node)();
boost::optional<double> as_double = YAML::as_if<double, boost::optional<double> >(node)();
boost::optional<std::string> as_string = YAML::as_if<std::string, boost::optional<std::string> >(node)();