c++ - 使用 move 构造函数抛出异常? (C++)

标签 c++ exception move

如果我有一个 Error 类型的对象 e 实现了一个 move 构造函数,将抛出 std::move( e ) 使用将 Error 的构造函数 move 到“复制”e,那么它是否避免制作对象的实际拷贝?所以如果我有

Error e;

throw std::move( e );

Error 的拷贝构造函数会不会被调用?当您的 move 构造函数是 noexcept(它应该是)但您的复制构造函数不是时,这很有趣。

最佳答案

§ 15.1 [except.throw]:

  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.

  2. 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]:

  1. The initialization that occurs in the form

    T x = a;

, 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]:

  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):

  • 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 构造函数来构造实际的异常对象(即使 std::move(e) 未在 throw 表达式中显式调用),但不会调用其匹配的处理程序(如果试图被捕获按值(value))。

关于c++ - 使用 move 构造函数抛出异常? (C++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25534628/

相关文章:

c++ - Mat 单元格在 OpenCV 中设置为 NULL?

c# - 一个解决方案中的非托管 DLL 项目和托管 WinForms 应用程序

c# - 如何处理 System.CannotUnloadAppDomainException?

c# - 用鼠标 move 矩形

c++ - 完美转发和临时对象的范围

C# Mysql 将行 move 到另一个表并获取单元格的最大值

c++ - 将 unsigned int 的指针传递给 long int 的指针

c++ - C++ 中的 nothrow delete 是什么?

exception - Installshield:EnumServicesStatus 抛出异常问题

python - 什么时候应该在 Python 中使用 Try-Except 语句?