只是一个简单的问题。
之间有什么区别吗?void f(Foo x) try
{
...
}
catch(exception& e)
{
...
}
和
void f(Foo x)
{
try { ... }
catch (exception& e)
{
...
}
}
如果不是,为什么函数尝试块(构造函数的初始化列表被搁置)?如果Foo
的副本构造函数在x
传递给f
时抛出异常,会发生什么?
答案 0 :(得分:10)
构造函数中只需要函数try块。在所有其他情况下,通过将函数的整个主体包含在普通的try / catch块中,可以实现完全相同的效果。
如果用于初始化参数的复制构造函数抛出异常,则在函数调用之前发生。它不能被函数try块或函数中的异常处理程序捕获,因为函数没有被调用。
答案 1 :(得分:6)
有些事情是允许的,因为它们更难以禁止它们。在一些但不是所有函数体上允许函数try块会使语法和编译器更复杂。
答案 2 :(得分:3)
刚刚发现了这个Dr. Dobb's article中的一个有趣点(尽管很老):
...请记住,无法在function-try-block处理程序中返回值。因此,对非空函数使用函数try块是没有意义的
这是他们的代码示例:
int f()
try
{
...
}
catch(Error &e)
{
// oops, can't return int from here!
}
这实际上意味着函数try块比“常规”try块弱,并且除了在构造函数之外,不应该使用它们。
(这篇文章是从2000年开始的,所以如果有人会评论目前的标准是否仍然如此,那就太好了)
答案 3 :(得分:1)
为了在构造函数初始化列表中捕获异常,明确添加了函数try块。
在您的示例中,没有构造函数初始化,因此两种形式之间没有区别。