I'm referring to this question. To make it easier to grasp it, I should note that the mentioned booked C++ Primer tells the readers to implement move-operations - if possible - in a way that no exceptions can be thrown and specifying the keyword noexcept
if so. This leads to a set of four declarations of the copy- and move operations:
HasPtr(const HasPtr& hp)
HashPtr& operator=(const HasPtr& rhs)
HasPtr(HasPtr&& hp) noexcept
HashPtr& operator=(HasPtr&& rhs) noexcept
Or, if we apply the copy-and-swap idiom:
HasPtr(HasPtr& hp)
HasPtr& operator=(HasPtr rhs) // non-reference parameter, copy-and-swap-assigment operator, either calls copy- or move-constructor
HasPtr(HasPtr&& hp) noexcept
Like the book and the original question, I'm interested in the consequences of low-level efficiency:
In the case of HasPtr
we need to allocate memory if the copy-assignment constructor receives a lvalue
as parameter and allocating memory can throw a bad_alloc
exception (if not nothrow
is used). So we shall not add noexcept
to the copy-assignment operator! Regarding the original question, I assume that the compiler cannot preserve some extra work for possible stack-unwinding of the copy-assignment constructor. Is this correct?
The standard library uses move_if_noexcept which returns an rvalue
the move-constructor doesn't throw exceptions. So I assume no drawbacks, because the move-constructor specifies noexcept
. Is this correct?
The only remaining thing is this post from Scott Meyers, he mentions the loss of control, when destruction happens and extra pointer copies.
Thank you
PS: Honestly. I wasn't able to add this a comment to the original question, because it is to big in size of characters. I tried to add a similar post as answer and ask if I'm right with my assumptions. People didn't liked that. So I open a new question.