my comment in reply to martin_sustrik.

I wanted to post some code into the comment but I finally gave up. I will post it here instead. Disclaimer: this code has not been compiled.


class foo
{
public:
~foo() {}
foo(foo&& other) {
guts.a = std::move(other.a); // no-fail
}
foo& operator=(foo other) { // no-fail
using std::swap;
swap(guts.a, other.guts.a);
return *this;
}
static optional<foo> init() {
optional<foo> result;
type guts = {}; // ~type() cleans up on exit
guts.a.reset(new(std::nothrow) int(5));
if (!guts.a) {return result;} // no foo constructed
result.reset(foo(guts)); //no-fail move construction
return std::move(result); // no-fail move of result
}
int do() {return guts.a.get();} // a cannot be empty
private:
struct type { std::unique_ptr<int> a; };
type guts;
foo(); // disabled
foo(const foo&); // disabled
foo(type&& gutsArg) {guts.a = std::move(gutsArg.a);} // no-fail
};

auto MyFoo = foo::init();
if (!MyFoo) return;
MyFoo->do();

if you want to return a detailed error from init() change init() to return a tuple:


static std::tuple<error, optional<foo>> init();
and use tie to break the result into local vars:

optional<foo> MyFoo;
error MyError;
std::tie(MyError, MyFoo) = foo::init();