首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++11复制elison和exception (catch参数)

C++11复制elison和exception (catch参数)
EN

Stack Overflow用户
提问于 2017-03-07 16:07:53
回答 1查看 398关注 0票数 4

在代码检查之后,我们在try/catch块中出现了复制elison的问题。在阅读了本页:cpp参考指南,特别是本段落之后:

在处理异常时,如果catch子句的参数与抛出的异常对象的类型相同(忽略顶级cv限定),则将省略该副本,catch子句的主体将直接访问异常对象,就像通过引用捕获一样。

我认为catch中的参数的复制省略将自动执行,但是其中一个审阅者运行了一个简单的测试,显示编译器没有执行复制省略:

代码语言:javascript
复制
#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;
 }

在编译时:

代码语言:javascript
复制
g++ a.cpp -std=c++11 -O3

我得到了以下输出

代码语言:javascript
复制
COPY CONSTRUCTOR
COPY CONSTRUCTOR
terminate called after throwing an instance of 'A'
Aborted (core dumped)

我期望得到一个类似于(抛出异常时只调用一个复制构造函数)的输出:

代码语言:javascript
复制
COPY CONSTRUCTOR
terminate called after throwing an instance of 'A'
Aborted (core dumped)

该测试已在LinuxUbuntu16.04下运行,g++版本如下:

代码语言:javascript
复制
 g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609

测试用例无效还是我对副本省略的理解有误?非常感谢你的帮助

EN

回答 1

Stack Overflow用户

发布于 2017-03-07 16:32:57

在处理异常时,如果catch子句的参数与抛出的异常对象的类型相同(忽略顶级cv限定),则忽略副本.

关于优惠的措辞过于强硬。这是一个复制省略是允许的的例子列表。那应该是:“副本可以省略”。

编译器似乎没有执行复制省略,尽管它是允许的。

标准(草案)的相关引文:

class.copy.elision /1 ..。这种复制/移动操作的省略,称为复制省略,在以下情况下是允许的(可以合并以消除多个副本): class.copy.elision / 1.3 当异常处理程序的异常声明(除条款外)将同一类型的对象(cv-资格除外)声明为异常对象时,可以通过将异常声明作为异常对象的别名来省略该复制操作,如果程序的含义将不变,除非执行异常声明声明所声明的对象的构造函数和析构函数。 注释:不能从异常对象中移动,因为它始终是一个lvalue。 - 尾注 

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42652965

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档