c++ 获取存储在yaml-cpp的YAML::Node中的值的类型

ymzxtsji  于 2023-08-09  发布在  其他
关注(0)|答案(2)|浏览(253)

给定此代码:

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

wydwbb8l

wydwbb8l1#

解析时抛出大量异常会影响解析速度。不知道为什么yaml-cpp没有is_type<T>方法或类似于std::optionalstd::expected getter的方法
使用Boost的一个很好的解决方法-将您自己的模板专门化注入到YAML命名空间并返回std::optional(如果您没有C++17,则返回boost::optional
// yaml-cpp/patch.hpp

#pragma once

#include <yaml-cpp/yaml.h>

#include <optional>
#include <string>

namespace YAML {

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

  std::optional<T> operator()() const {
    std::optional<T> val;
    T decoded;
    if ((node.m_pNode != nullptr) && convert<T>::decode(node, decoded)) {
      val = std::move(decoded);
    }

    return val;
  }
};

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

  std::optional<std::string> operator()() const {
    std::optional<std::string> val;
    std::string decoded;
    if ((node.m_pNode != nullptr) && convert<std::string>::decode(node, decoded)) {
      val = std::move(decoded);
    }

    return val;
  }
};

} // namespace YAML

字符串
然后可以运行类似于

std::optional<bool> as_bool          = YAML::as_if<bool, std::optional<bool> >(node)();
std::optional<int> as_int            = YAML::as_if<int, std::optional<int> >(node)();
std::optional<double> as_double      = YAML::as_if<double, std::optional<double> >(node)();
std::optional<std::string> as_string = YAML::as_if<std::string, std::optional<std::string> >(node)();


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

vq8itlhq

vq8itlhq2#

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

try {
  int value = data.as<int>();
  // do something
} catch (const BadConversion& e) {
  // do something else
}

字符串

相关问题