给定此代码:
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 节点"数据"中包含的数据是整数、浮点数还是字符串?注意:我不想检查节点是否是标量、映射、序列等。
解析时引发大量异常会影响解析速度。不知道为什么yaml-cpp
没有is_type<T>
方法或类似于std::optional
或std::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 个默认值。这可能比处理异常更快,也可能不快,我还没有测试过。
您可以尝试将节点转换为每种类型:
try {
int value = data.as<int>();
// do something
} catch (const BadConversion& e) {
// do something else
}