乘以嵌套的try-catch

时间:2016-08-03 21:10:16

标签: c++ try-catch

我有一个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;
    }
  }
}

嗯,越深越深的嵌套告诉我,这不是编写该代码的最佳方式。

有关如何改进设计的任何建议吗?肯定会建议平坦的筑巢。

3 个答案:

答案 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;