Consider this. There is a non-copyable, non-movable class, and there is some predicated defined for it:
struct AA
{
AA(AA const& otehr) = delete;
AA(AA && otehr) = delete;
AA& operator = (AA const& otehr) = delete;
AA& operator = (AA && otehr) = delete;
AA(int something) { }
bool good() const { return false; }
};
Because of guaranteed copy/move-elision in C++17 we can have:
auto getA() { return AA(10); }
The question is: how can one define getGoodA, that will forward getA in case it returned good and will throw an exception otherwise? Is it possible at all?
auto getGoodA()
{
auto got = getA();
if (got.good()) return got; // FAILS! Move is needed.
throw std::runtime_error("BAD");
}
If we had got contract checking in C++20 you would have been able to write something like:
(At least I think so - I'm not entirely clear on the type of the
aareturn pseudo-variable; it would need to be a reference to the returned object in its return location.) Unfortunately contracts were removed from C++20 so it'll be some time before we can write this.Assuming you can't modify
getA, the only way for now is to return a wrapper class fromgetGoodA. The obvious solution would beunique_ptr, but we don't actually need to perform heap allocation; a delayed-construction wrapper will do just as well:Here I've given
BBa reference-style interface, allowing you to writeAA& aa = getGoodA(i), but you could equally give it a pointer-style interface (operator*andoperator->) or even copy the interface ofAA.