Re: Class invariants and implicit move constructors (C++0x)
On 15 Aug., 21:19, Scott Meyers wrote:
Howard Hinnant wrote:
Example: One can insert into, and erase from vector<Widget>. Thou=
gh
there will be intermediate stages of broken invariants of Widget,
these will not be exposed unless the insert throws. After a normally=
-
ending erase and insert, all Widgets in the vector will have satisfied
invariants.
Unfortunately, any temporaries created for the insert may not.
[...]
Here, Howard was assuming that the destructor was also compiler-
generated.
Maybe, the rules could be just a tad more restrictive. For example,
also inhibiting the generation of move operations in case there is a
user-declared DESTRUCTOR seems like a reasonable idea to me at the
moment.
Consider:
std::vector<Widget> vw;
vw.push_back(Widget(x, y, z)); // asserts during destruction of=
temporary
This piece of code would be okay with the above rule change.
> the case of ~Widget(), the invariant likely won't matter. However=
if
> ~Widget() is defined with an assertion check, then we have a noisy
> error that can be corrected.
I'm not sure how to correct this noisy error. We don't want to remove the
invariant check from ~Widget, because presumably it's there to detect cor=
rupted
objects.
The easy fix is to write your own move constructor that sets the
mutable cacheIsUpToDate member from the source to false. As
alternative, I suggested to replace the bool type with a class that
wraps a bool and is automatically set to false if you move from it
(see replace_on_move<bool,false>).
Cheers!
SG