Pum*_*kko 6 c++ exception copy-constructor
在阅读了关于cppreference的复制省略后,我想玩异常和复制省略.所以我在coliru上用gcc 7.2编写了以下代码
#include <iostream>
class Exception
{
public:
Exception() { std::cout << "constructed\n"; }
Exception(Exception& other) {std::cout << "copy constructed\n";}
Exception(const Exception& other) {std::cout << "copy constructed\n";}
Exception(Exception&& other) {std::cout << "move constructed\n";}
};
void foo()
{
throw Exception();
}
int main()
{
try
{
foo();
}
catch(Exception e )
{
}
}
Run Code Online (Sandbox Code Playgroud)
产量
构造的
复制品
我们可以看到复制构造函数被调用,即使用-O2调用gcc也会发生这种情况.在我看来,此代码应该有资格根据以下条款复制elision:
处理异常时,如果catch子句的参数与抛出的异常对象具有相同的类型(忽略顶级cv限定),则省略该副本,并且catch子句的主体直接访问异常对象,如如果被引用抓住了
那么为什么复制构造函数被调用?为什么复制省略在这种情况下不起作用?
cppreference对此不准确.事实上,除了常量表达式(constexpr)或常量初始化(静态或线程局部)之外,实际上无法保证副本将被省略.在您的示例中并非如此.
请参阅当前C++ 17草案中的[class.copy.elision]/1(强调我的):
当满足某些标准时,...... 在下列情况下,允许复制/移动操作的省略,称为复制省略:
- 在throw-expression中,当操作数是非易失性自动对象的名称(函数或catch子句参数除外),其范围不会超出最内层封闭try-block的末尾(如果有的话) 1),通过将自动对象直接构造到异常对象中,可以省略从操作数到异常对象的复制/移动操作
在需要常量表达式和常量初始化的上下文中计算表达式时,需要复制省略.
这意味着有一天它可能被实现为编译器优化,但目前情况并非如此.
这将是明智因此对catch通过const&暂且(也以避免意外的切片).
| 归档时间: |
|
| 查看次数: |
189 次 |
| 最近记录: |