catch 语句中可以发生复制省略吗?
考虑一个带有带有副作用的复制构造函数的异常类。
编译器可以跳过在这里调用复制构造函数吗:
try {
throw ugly_exception();
}
catch(ugly_exception) // ignoring the exception, so I'm not naming it
{ }
这个怎么样:(
try {
something_that_throws_ugly_exception();
}
catch(ugly_exception) // ignoring the exception, so I'm not naming it
{ }
是的,我知道这一切都非常丑陋,这是受到 另一个问题)
Consider an exception class with a copy constructor with side-effects.
Can a compiler skip calling the copy constructor here:
try {
throw ugly_exception();
}
catch(ugly_exception) // ignoring the exception, so I'm not naming it
{ }
What about this:
try {
something_that_throws_ugly_exception();
}
catch(ugly_exception) // ignoring the exception, so I'm not naming it
{ }
(yes, I know this is all very ugly, this was inspired by another question)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为这是特别允许的。对于 C++03,15.1/3 说:
12/15 说:
秘密隐藏位置由标准定义为临时的,因此对于复制省略是有效的。
编辑:哎呀,我现在已经进一步阅读了。 15.1/5:
并没有变得更清楚。
无论它实际上是否会...如果 catch 子句要重新引发异常(包括它调用可能这样做的不可见代码),那么实现需要“称为异常对象的临时对象”仍然存在。因此,何时可以进行复制省略可能会受到一些限制。显然,空的 catch 子句不能重新引发它。
I think this is specifically permitted. For C++03, 15.1/3 says:
and 12/15 says:
So, the secret hiding place where in-flight exceptions are kept, is defined by the standard to be a temporary, and hence is valid for copy-elision.
Edit: oops, I've now read further. 15.1/5:
Doesn't get much clearer.
Whether it actually will... if the catch clause were to re-raise the exception (including if it called non-visible code that might do so), then the implementation needs that "temporary object called the exception object" still to be around. So there might be some restrictions on when that copy elision is possible. Clearly an empty catch clause can't re-raise it, though.
是的。如果
catch
通过引用捕获异常,那么就不会存在复制(嗯,这是根据定义)。但我认为这不是你的问题,而且我相信你编写的代码是故意编写的,没有提及引用。如果是这样的话,那么是的,即使在这种情况下,副本也可以被省略。实际上,
catch
中变量的初始化理论上是直接初始化。如果可能的话,编译器可以省略直接初始化中的复制。C++03 §8.5/14 读取,
Yes. If the
catch
catches the exception by reference, then there will not be copy (well, that is by definition).But I think that is not your question, and I believe the code which you've written is written on purpose with no mention of reference. If that is the case, then yes, even in this case, copy can be elided. Actually initialization of the variable in the
catch
is direct-initialization in theory. And copy in a direct-initialization can be elided by the compiler where it's possible.C++03 §8.5/14 reads,
是的,在投掷和接球过程中都可以忽略它。对于捕获,只有当 catch 子句中指定的类型与异常对象的类型相同(除了 cv 限定)时,才可以忽略它。有关更正式和详细的描述,请参阅 C++11 12.8/31。
Yes, it can be elided both during throwing and catching. For catching it can be elided only when the type specified in the catch clause is the same (save for cv-qualifications) as the type of the exception object. For more formal and detailed description see C++11 12.8/31.