【问题标题】:Multiply nested try-catch [duplicate]乘以嵌套的try-catch [重复]
【发布时间】:2016-12-09 18:30:06
【问题描述】:

我有一个yaml-cpp,它总是转换成std::string,有时也转换成别的东西。例如,如果字符串实际上是"3.14",它也会转换为double。我首先想尝试int,然后是double,然后是bool,如果这不起作用,请转换为std::string。好吧,让我们嵌套那些try-catches:

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

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

关于如何改进这里的设计有什么建议吗?当然建议使用平面嵌套。

【问题讨论】:

  • 不确定,只是尝试一下 {} 和 catch(...)?然后通过一个函数检查Exception...Like ExceptionStatement(Exception e)。

标签: c++ try-catch


【解决方案1】:

你可以把它放在这样的函数中:

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

【讨论】:

    【解决方案2】:

    换个方式试试:
    转成字符串,再试试bool等
    一切都在一个 try-catch 中并忽略异常。

    【讨论】:

    • 好主意,谢谢!
    【解决方案3】:

    对正常控制流使用异常被认为是不好的做法。在这种情况下,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;
    

    【讨论】:

      猜你喜欢
      • 2013-05-26
      • 2022-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-15
      • 2016-08-08
      • 1970-01-01
      • 1970-01-01
      • 2019-11-12
      相关资源
      最近更新 更多