问题
just a quick question. Is there any difference between
void f(Foo x) try
{
...
}
catch(exception& e)
{
...
}
and
void f(Foo x)
{
try { ... }
catch (exception& e)
{
...
}
}
?
If no, why are function try blocks for (the case of initialization lists for constructors being put aside) ? What happens if the copy constructor of Foo
throws an exception when x
is passed to f
?
回答1:
Function try blocks are only ever needed in constructors. In all other cases exactly the same effect can be achieved by enclosing the entire body of the function in a normal try/catch block.
If the copy constructor used to initialize a parameter throws an exception this happens before the function call. It cannot be caught by a function try block or exceptional handler in the function as the function doesn't get called.
回答2:
Some things are allowed because it would be harder to disallow them. Allowing function try blocks on some, but not all function bodies would make the grammar and compilers more complicated.
回答3:
Just spotted an interesting point in this Dr. Dobb's article (although quite old):
...remember that you can't return a value inside a function-try-block handler. So it makes no sense to use a function try block for a non-void function
and this is their code example:
int f()
try
{
...
}
catch(Error &e)
{
// oops, can't return int from here!
}
Which actually means that function try blocks are weaker than "regular" try blocks and their use should be discouraged other than in constructors.
(the article is from 2000, so it'd be nice if someone would comment on whether this is still so in the current standard)
回答4:
Function try blocks were added expressly for the purpose of catching exceptions in constructor initialization lists.
In your example there are no constructor initializations, so there is no difference between the two forms.
来源:https://stackoverflow.com/questions/3889811/function-try-blocks-but-not-in-constructors