【问题标题】:try-catch without argument, use reference?try-catch 不带参数,使用参考?
【发布时间】:2016-09-15 15:13:43
【问题描述】:

前面很多回答都提到过,应该按值抛出异常,按引用捕获异常([A][B]),比如

try {
    // throw std::exception();
}
catch(std::exception &e) {
    // handle exception
}

如果您不打算使用异常本身(即使您应该),这将在编译时生成烦人的“未使用变量”警告。为避免这些,您可以省略参数(上例中的e),此时catch 块将触发已定义的异常,但您无需担心变量。

但是,几乎每次我看到这个无变量的 catch 块时,它都不是通过引用声明的,而是通过值声明的,如

try {
    // throw std::exception();
}
catch(std::exception) {
    // handle exception
}

即使Our Lord and Savior 也以这种方式发布了答案(others 也是如此)。不过,我确实找到了one instance,其中使用了引用。

由于没有使用变量,所以切片不是问题,因此按值捕获或按引用捕获之间应该没有有效的区别。但是,为什么人们似乎会区分有变量和无变量的情况?省去添加与号的工作?

并且,尽管可能进行微优化(特别是考虑到异常异常应该如何),但按值情况不会产生强制转换成本(查看catch 是否适合抛出的异常)缓解什么时候通过引用完成?

【问题讨论】:

  • 无参考答案的链接适用于 C#,而不是 C++。完全不同的语言和同样不同的语义。
  • 至于未使用的警告,从 C++17 开始,您有 [[maybe_unused]] attribute(一些大型编译器已经实现)。
  • 如果你不使用异常,不要捕获它。
  • @user1810087 但是这里使用了异常,只是它的值被忽略了。

标签: c++ exception


【解决方案1】:

由于没有使用变量,所以切片不是问题。

但是在切片的情况下你会强制复制。并不是说这特别成问题,因为异常应该在很少使用的代码路径上。

但是,如果您在复制/切片之后将异常作为嵌套异常重新抛出,那么最终结果可能会令人惊讶。例如:

struct E : std::runtime_error { using std::runtime_error::runtime_error; };

throw E("");

...

catch(std::runtime_error)
{
    std::throw_with_nested(std::logic_error(""));
} 



... further down the call stack...

catch(std::exception& e)
{
   // what did we actually catch? std::runtime error nested in a std::logic_error, or
  // E nested in a std::logic_error?
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-02
    • 2014-03-04
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多