yaml里的as(模板)函数


googletest的测试代码

#define YAML_CPP_API
#include "./yaml-cpp/yaml.h"

TEST(yaml, 0读取)
{
    try {
        YAML::Node config = YAML::LoadFile(R"(C:\config_test.yml)");  //读取yml文件
        YAML::Node node = config["AAA"];
        std::cout << "name:" << node.as<std::string>() << std::endl;

        YAML::Node stu = config["BBB"];
        std::cout << "name:" << stu["name"].as<std::string>() << std::endl;
        std::cout << "sex:" << stu["sex"].as<std::string>() << std::endl;
        std::cout << "age:" << stu["age"].as<int>() << std::endl;

        //config["sex"] = 20;

        //std::ofstream fout(filePath);
        //fout << config;
    }
    //catch (YAML::ParserException& e) {
    catch (...) {
        //std::cout << e.what() << "\n";
        std::cout << "123" << "\n";
    }
}

 yml文件内容:


无压管道平接方式: 0001
管道最小坡度:
  name: chen
  age: 18
  sex: 男
  class: 11
管径最小设计坡度:
    400: 0.0015
    500: 0.0012
管长精度: 0
标高精度: 0
坡度精度: 0
尺寸精度: 0
坐标精度: 0
图层: 0

有两个as函数:

// access functions
template <typename T>
inline T Node::as() const {
  if (!m_isValid)
    throw InvalidNode(m_invalidKey);
  return as_if<T, void>(*this)();
}

template <typename T, typename S>
inline T Node::as(const S& fallback) const {
  if (!m_isValid)
    return fallback;
  return as_if<T, S>(*this)(fallback);
}

它们调用了as_if函数。这个函数有特化以及偏特化版本

当执行node.as<std::string>()时,会调用一个特化版本:as_if<std::string, void>。

当执行node.as<int>()时,会调用偏特化版本as_if<int, void>,继而通过convert<T>::decode(node, t)解析出int值。

Convert最终会调用:
注意,这个函数只接受字符类型的变量类型:

template <typename T>
typename std::enable_if<!(std::is_same<T, unsigned char>::value ||
                          std::is_same<T, signed char>::value), bool>::type
ConvertStreamTo(std::stringstream& stream, T& rhs) {
  if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) {
    return true;
  }
  return false;
}
}

注意,还有一个string的偏特化版本as_if<std::string, S>,它的operator是需要传入参数的。也说明了特化版本和泛化版本可以完全不同?

// access

// template helpers
template <typename T, typename S>
struct as_if {
  explicit as_if(const Node& node_) : node(node_) {}
  const Node& node;

  T operator()(const S& fallback) const {
    if (!node.m_pNode)
      return fallback;

    T t;
    if (convert<T>::decode(node, t))
      return t;
    return fallback;
  }
};

template <typename S>
struct as_if<std::string, S> {
  explicit as_if(const Node& node_) : node(node_) {}
  const Node& node;

  std::string operator()(const S& fallback) const {
    if (node.Type() == NodeType::Null)
      return "null";
    if (node.Type() != NodeType::Scalar)
      return fallback;
    return node.Scalar();
  }
};

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

  T operator()() const {
    if (!node.m_pNode)
      throw TypedBadConversion<T>(node.Mark());

    T t;
    if (convert<T>::decode(node, t))
      return t;
    throw TypedBadConversion<T>(node.Mark());
  }
};

template <>
struct as_if<std::string, void> {
  explicit as_if(const Node& node_) : node(node_) {}
  const Node& node;

  std::string operator()() const {
    if (node.Type() == NodeType::Null)
      return "null";
    if (node.Type() != NodeType::Scalar)
      throw TypedBadConversion<std::string>(node.Mark());
    return node.Scalar();
  }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值