使用move构造函数引发异常? (C ++) [英] Using the move constructor to throw exceptions? (C++)

查看:117
本文介绍了使用move构造函数引发异常? (C ++)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我具有实现移动构造函数的类型为Error的对象e,将使用Error的移动构造函数抛出std::move( e )来复制" e,因此它避免了实际对象的副本?所以如果我有

If I have an object e of type Error which implements a move constructor, will throwing std::move( e ) use the move constructor of Error to "duplicate" e, so does it avoid making an actual copy of the object? So if I have

Error e;

throw std::move( e );

是否调用Error的副本构造函数?当您的move构造函数是noexcept(应该是),而复制构造函数不是该变量时,这是很有意思的.

will the copy constructor of Error be called or not? This is of interest when your move constructor is noexcept (as it should be), but your copy constructor isn't.

推荐答案

第15.1节[throw.throw]:

§ 15.1 [except.throw]:

  1. 引发异常复制初始化(8.5、12.8)临时对象, 称为异常对象.这 临时是左值,用于初始化在匹配处理程序中命名的变量.

  1. Throwing an exception copy-initializes (8.5, 12.8) a temporary object, called the exception object. The temporary is an lvalue and is used to initialize the variable named in the matching handler.

当抛出的对象是类对象时,即使删除了复制/移动操作(12.8),也可以访问为复制初始化选择的构造函数和析构函数.

When the thrown object is a class object, the constructor selected for the copy-initialization and the destructor shall be accessible, even if the copy/move operation is elided (12.8).

§8.5 [dcl.init]:

§ 8.5 [dcl.init]:

  1. 初始化形式为

  1. The initialization that occurs in the form

T x = a;

,以及参数传递,函数返回,引发异常(15.1),处理异常 (15.3),聚合成员初始化(8.5.1)称为 copy-initialization . [注意:复制初始化可以调用移动(12.8). —尾注]

, as well as in argument passing, function return, throwing an exception (15.1), handling an exception (15.3), and aggregate member initialization (8.5.1) is called copy-initialization. [ Note: Copy-initialization may invoke a move (12.8). —end note ]

§12.8 [class.copy]:

§ 12.8 [class.copy]:

  1. 满足或将要满足复制操作的省略标准时,除以下事实外: object是一个函数参数,要复制的对象由左值,重载分辨率指定为 选择复制程序的构造函数,首先执行,就好像该对象是由右值指定的.
  1. When the criteria for elision of a copy operation are met or would be met save for the fact that the source object is a function parameter, and the object to be copied is designated by an lvalue, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue.

上述复制删除标准包括以下内容(第12.8节[class.copy]/p31):

The aforementioned criteria for copy-elision include the following (§12.8 [class.copy]/p31):

    throw-expression 中,如果操作数是非易失性自动对象的名称( 函数或catch子句参数),其作用域不超出最内层的末尾 包含 try-block (如果有),则从操作数到异常的复制/移动操作 通过将自动对象直接构造到异常对象中,可以省略对象(15.1)
  • in a throw-expression, when the operand is the name of a non-volatile automatic object (other than a function or catch-clause parameter) whose scope does not extend beyond the end of the innermost enclosing try-block (if there is one), the copy/move operation from the operand to the exception object (15.1) can be omitted by constructing the automatic object directly into the exception object

异常的复制初始化可能会调用move-constructor构造实际的异常对象(即使未在throw表达式中显式调用std::move(e)),但也不能调用其匹配处理程序(如果试图捕获它)按值).

Copy-initialization of an exception may invoke a move-constructor to construct the actual exception object (even if std::move(e) is not explicitly invoked in a throw excpression), but not its matching handler (if tried to be caught by value).

这篇关于使用move构造函数引发异常? (C ++)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆