|
Boost : |
Subject: Re: [boost] [review] Review of Outcome v2 (Fri-19-Jan to Sun-28-Jan, 2018)
From: Jonathan Müller (jonathanmueller.dev_at_[hidden])
Date: 2018-02-01 07:01:00
On Feb 1, 2018 7:56 AM, "Emil Dotchevski via Boost" <boost_at_[hidden]>
wrote:
On Wed, Jan 31, 2018 at 10:30 PM, Gavin Lambert via Boost <
boost_at_[hidden]> wrote:
> On 1/02/2018 19:09, Emil Dotchevski wrote:
>
>> 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.
>>
>
> The factory itself provides that guarantee. One such pseudo-code
> implementation might be:
>
> static std::unique_ptr<A> A::create(args...) noexcept
> {
> // the constructor is itself noexcept and cannot fail
> std::unique_ptr<A> a(new (std::nothrow) A(arg1));
> if (!a)
> return nullptr;
>
> if (!a->private_init_stuff(arg2, arg3, ...))
> return nullptr;
>
> return a;
> }
>
This does not protect the user at all:
std::unique_ptr<A> a=A::create();
a->foo(); //undefined behavior
Compare to:
static std::unique_ptr<A> A::create(args...)
{
std::unique_ptr<A> a(new A(arg1)); //new throws on error, A::A() throws
on error
return a;
}
And then:
std::unique_ptr<A> a=A::create();
a->foo(); //Okay, a is guaranteed to be valid.
Yeah but you can write stupid code with anything:
```
std::unique_ptr<A> a;
try
{
a =A::create();
}
catch (...) {}
a->foo(); // ups
```
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk