我有一个yaml-cpp,它总是转换为std::string
,有时也转换为其他内容。例如,如果字符串实际上是"3.14"
,它也会转换为double
。我首先要尝试int
,然后double
,然后bool
,如果这不起作用,请转换为std::string
。好吧,让我们嵌套那些try
- catch
es:
try {
const int a = node.as<int>();
std::cout << "int!" << a << std::endl;
} catch (YAML::BadConversion) {
try {
const double a = node.as<double>();
std::cout << "double!" << a << std::endl;
} catch (YAML::BadConversion) {
try {
const bool a = node.as<bool>();
std::cout << "bool!" << a << std::endl;
} catch (YAML::BadConversion) {
const std::string a = node.as<std::string>();
std::cout << "string!" << a << std::endl;
}
}
}
嗯,越深越深的嵌套告诉我,这不是编写该代码的最佳方式。
有关如何改进设计的任何建议吗?肯定会建议平坦的筑巢。
答案 0 :(得分:4)
你可以把它放在像这样的函数中:
template<typename N, typename T>
bool tryParseNode(N& node, T& val) {
try {
val = node.as<T>();
return true;
} catch (YAML::BadConversion) {
return false;
}
}
然后:
int a;
double d;
bool b;
std::string s;
if (tryParseNode(node, a) {
std::cout << "int!" << a << std::endl;
}
else if (tryParseNode(node, d) {
std::cout << "double!" << d << std::endl;
}
else if (tryParseNode(node, b) {
std::cout << "bool!" << b << std::endl;
}
else if (tryParseNode(node, s) {
std::cout << "string!" << s << std::endl;
}
答案 1 :(得分:2)
反过来试试:
转换为字符串,然后尝试bool等。
单个try-catch中的所有内容都会忽略异常。
答案 2 :(得分:1)
使用正常控制流的异常被认为是不好的做法。在这种情况下,as
方法使用`YAML :: convert :: decode'方法尝试将节点转换为请求的类型,如果失败而不是抛出异常,则返回false。
int anInt;
double aDouble;
bool aBool;
if (YAML::convert <int>::decode (node, anInt))
std::cout << "int!" << anInt << std::endl;
else
if (YAML::convert <double>::decode (node, aDouble))
std::cout << "double!" << aDouble << std::endl;
else
if (YAML::convert <bool>::decode (node, aBool))
std::cout << "double!" << aBool << std::endl;
else
std::cout << "string!" << node.as <std::string> () << std::endl;
可以进一步简化为
template <typename value_type>
std::optional <value_type> decode (YAML::Node const & Node)
{
value_type Value;
if (YAML::convert <value_type>::decode (node, Value))
return { Value };
else
return {};
}
if (auto anInt = decode <int> (node))
std::cout << "int!" << *anInt << std::endl;
else
if (auto aDouble = decode <double> (node))
std::cout << "double!" << *aDouble << std::endl;
else
if (auto aBool = decode <bool> (node))
std::cout << "double!" << *aBool << std::endl;
else
std::cout << "string!" << node.as <std::string> () << std::endl;