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