如果我有一个 Error
类型的对象 e
实现了一个 move 构造函数,将抛出 std::move( e )
使用将 Error
的构造函数 move 到“复制”e
,那么它是否避免制作对象的实际拷贝?所以如果我有
Error e;
throw std::move( e );
Error
的拷贝构造函数会不会被调用?当您的 move 构造函数是 noexcept
(它应该是)但您的复制构造函数不是时,这很有趣。
最佳答案
§ 15.1 [except.throw]:
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.
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]:
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]:
- 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/