简体   繁体   中英

Using the move constructor to throw exceptions? (C++)

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

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 [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 .

The aforementioned criteria for copy-elision include the following (§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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM