Try-catch不带参数,使用引用

try-catch without argument, use reference?

本文关键字:引用 参数 Try-catch      更新时间:2023-10-16

正如前面许多答案中提到的,应该按值抛出异常,并通过引用([A], [B])捕获异常,例如

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

如果你不打算使用异常本身(即使你应该),这将在编译时产生令人讨厌的"未使用的变量"警告。为了避免这些,您可以省略参数(上面示例中的e),此时catch块将触发定义的异常,但是您不需要为变量操心。

然而,几乎每次我看到这个无变量catch块时,它都不是通过引用声明的,而是通过值声明的,如
try {
    // throw std::exception();
}
catch(std::exception) {
    // handle exception
}

甚至我们的主和救主也以这种方式发布了一个答案(就像其他人一样)。不过,我确实发现了一个使用引用的实例。

由于没有使用变量,所以切片不是问题,因此按值捕获和按引用捕获之间应该没有有效的区别。然而,为什么人们似乎要区分有变量和无变量的情况呢?省去了添加&号的麻烦?

而且,微优化,因为它可能(特别是考虑到异常异常应该如何),按值的情况不产生铸造成本(看看catch是否适合抛出的异常)减轻时,通过引用?

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

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

但是,如果在复制/切片之后将异常作为嵌套异常重新抛出,那么最终结果可能会令人惊讶。例如:
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?
}