在代码检查之后,我们在try/catch块中出现了复制elison的问题。在阅读了本页:cpp参考指南,特别是本段落之后:
在处理异常时,如果catch子句的参数与抛出的异常对象的类型相同(忽略顶级cv限定),则将省略该副本,catch子句的主体将直接访问异常对象,就像通过引用捕获一样。
我认为catch中的参数的复制省略将自动执行,但是其中一个审阅者运行了一个简单的测试,显示编译器没有执行复制省略:
#include <iostream>
class A
{
public:
A(){}
A(const A&){
std::cout<<"COPY CONSTRUCTOR\n";
}
};
int main()
{
try {
throw A{};
} catch(A a) {
throw a;
}
return 0;
}在编译时:
g++ a.cpp -std=c++11 -O3我得到了以下输出
COPY CONSTRUCTOR
COPY CONSTRUCTOR
terminate called after throwing an instance of 'A'
Aborted (core dumped)我期望得到一个类似于(抛出异常时只调用一个复制构造函数)的输出:
COPY CONSTRUCTOR
terminate called after throwing an instance of 'A'
Aborted (core dumped)该测试已在LinuxUbuntu16.04下运行,g++版本如下:
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609测试用例无效还是我对副本省略的理解有误?非常感谢你的帮助
发布于 2017-03-07 16:32:57
在处理异常时,如果catch子句的参数与抛出的异常对象的类型相同(忽略顶级cv限定),则忽略副本.
关于优惠的措辞过于强硬。这是一个复制省略是允许的的例子列表。那应该是:“副本可以省略”。
编译器似乎没有执行复制省略,尽管它是允许的。
标准(草案)的相关引文:
class.copy.elision /1 ..。这种复制/移动操作的省略,称为复制省略,在以下情况下是允许的(可以合并以消除多个副本): class.copy.elision / 1.3 当异常处理程序的异常声明(除条款外)将同一类型的对象(cv-资格除外)声明为异常对象时,可以通过将异常声明作为异常对象的别名来省略该复制操作,如果程序的含义将不变,除非执行异常声明声明所声明的对象的构造函数和析构函数。 注释:不能从异常对象中移动,因为它始终是一个lvalue。 - 尾注
https://stackoverflow.com/questions/42652965
复制相似问题