try-catch没有参数,使用引用?

时间:2016-09-15 15:13:43

标签: c++ exception

正如许多以前的答案中所提到的,应该按值抛出异常并通过引用([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是否适合于抛出异常)当通过引用完成时减轻了吗?

1 个答案:

答案 0 :(得分:0)

  

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

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

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

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