|
Boost : |
Subject: Re: [boost] [contract] move operations and class invariants
From: Julien Blanc (julien.blanc_at_[hidden])
Date: 2017-12-01 08:23:46
Le 2017-12-01 02:52, Lorenzo Caminiti via Boost a écrit :
>
> 1. Is it OK to assume I can call is_valid() on a moved-from object (so
> I can put it to guard invariants, preconditions, etc. and also check
> it in user code where needed to satisfy preconditions)? Based on the
> replies to this email thread so far, I think the answers is "yes".
>
> 2. How useful is a class like the one above with "crippled" invariants
> and is_valid() preconditions on all its useful public methods like
> read()? The answer seems to be: not very useful. I guess that's the
> price to pay for the performance gain of moving objects around...
Nobody will care to check is_valid() before every call, especially if
validity is assumed in the majority of cases and invalidity a rare case.
Worse, people will forget to add it to their own functions
preconditions. Another thing to consider is that adding methods to the
class just for the sake of expressing the contract looks like thereâs
something broken in the design first.
As for guidelines, I strongly agree with what has been said, that
non-default-constructible and move-constructible are somewhat antagonist
and should raise a red flag.
As for usefulness, in an ideal world you would like the compiler (or a
static analysis tool) to check the contracts for you. Regarding move
semantics, thatâs the choice made by the rust compiler (reusing a
moved-from object is a compile time error). In C++, reusing a moved-from
object is perfectly valid, so you would have to resort to other
mechanisms to forbid it. IMHO a tool-friendly way (which, by the way, is
also user-friendly) to do that is using unique_ptr : the rule to check
(nullptr dereference) is much more likely to be implemented, the users
are much more likely to write x != nullptr preconditions.
Iâm not sure there are many cases where you, at the same time :
- need the object to be not constructible (always valid)
- need to transfer the ownership of the object
- canât afford the extra cost of a pointer (which is, by the way, not
more expensive than checking an is_valid() function).
Regards,
Julien
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk