Subject: Re: [boost] [review] Review of Outcome v2 (Fri-19-Jan to Sun-28-Jan, 2018)
From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2018-02-01 06:09:43
On Wed, Jan 31, 2018 at 8:24 PM, Gavin Lambert via Boost <
> On 1/02/2018 15:38, Emil Dotchevski wrote:
>> My question still stands though. If you don't use exceptions, in C++, how
>>> do you protect users from calling member functions on objects that have
>>> been initialized?
>> I mean haven't been initialized or failed to initialize.
> The usual technique to manage that is to separate no-fail construction
> (constructor) from fail-possible initialisation (an init() method).
This does not protect users from calling member functions on objects that
have not been initialized:
a.bar(); //forgot to call init, now what?
or that have failed to initialize:
a.init(); //failed, but nobody noticed
> Sometimes this requires weaker invariants than otherwise (eg. allowing an
> empty state).
I can state this more precisely: it _always_ requires no-fail partial
initialization with boolean semantics (e.g. a private bool member), which
member functions can use as a base to build the logic needed to detect
failures to establish the "real" invariants of the object, except in the
case when the type has a natural no-fail empty state, in which case yes,
member functions can safely assume all is good.
The common trend you'll notice is that you'll be writing code which is
either automatic or unnecessary if you use excptions to report failures.
Of course, people who don't use exception handling don't always write this
code (not to mention, writing it is prone to errors, especially under
maintenance), which is to say they have no defense against this type of
> The factory method technique also allows somewhat restoring a stronger
> invariant -- only the constructor and destructor need to cope with empty or
> otherwise uninitialised instances; other methods can be reasonably assured
> that no such instances escaped the factory method.
This is true only if you use exceptions to report errors from the factory.
Otherwise it is most definitely NOT reasonable for member functions to
assume that the object has been initialized, because nothing guarantees
that an error reported by the factory wasn't ignored.