6

鉴于此代码:

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 节点“数据”中包含的数据是整数、浮点数还是字符串?注意:我不想检查节点是否是标量、映射、序列等。

4

2 回答 2

3

您可以尝试将节点转换为每种类型:

try {
  int value = data.as<int>();
  // do something
} catch (const BadConversion& e) {
  // do something else
}
于 2013-11-15T06:53:10.877 回答
2

在解析时抛出大量异常会影响您的解析速度。不知道为什么yamlcpp没有is_type<T>方法或类似于std::optionalstd::expected吸气剂的东西

使用 Boost 解决它的黑客方法 - 将您自己的模板专业化注入YAML命名空间并返回boost::optional(或者std::optional如果您有 C++17)

namespace YAML
{
    template <typename T>
    struct as_if<T, boost::optional<T> >
    {
        explicit as_if(const Node& node_) : node(node_) {}
        const Node& node;

        const boost::optional<T> operator()() const
        {
            boost::optional<T> val;
            T t;
            if (node.m_pNode && convert<T>::decode(node, t))
                val = std::move(t);

            return val;
        }
    };

    // There is already a std::string partial specialisation, so we need a full specialisation here
    template <>
    struct as_if<std::string, boost::optional<std::string> >
    {
        explicit as_if(const Node& node_) : node(node_) {}
        const Node& node;

        const boost::optional<std::string> operator()() const
        {
            boost::optional<std::string> val;
            std::string t;
            if (node.m_pNode && convert<std::string>::decode(node, t))
                val = std::move(t);

            return 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)();

这里的总建设成本是 4 个可选值 + 4 个默认值。这可能会也可能不会比处理异常更快,我没有测试过。

于 2020-03-03T01:12:52.823 回答