On 5/04/2019 22:06, Andrzej Krzemienski wrote:
I do not mind never-empty guarantee in principle. My problem is that providing it involves too much overhead. The costs outweigh the benefit. If there was a way to provide the never-empty guarantee for free, I would be a strong proponent of it.
I agree with that; as I said elsewhere I would be (relatively) happy to pay that overhead for a strong-guarantee variant. I don't see sufficient value in "never-empty" by itself to justify it. But, maybe others have different lines in the sand.
This is the type of code that I consider "requiring special attention". If the function throws it leaves x in a valid but unspecified state. I do not care much about "valid", but my concern is about "unspecified". I would never want anyone to observe the state of this object. Therefore I would rather change the signature of function f() like this:
template <class T> std::vector<T> f(std::vector<T> const & y ) { return std::vector<T>{y}; }
So that it is guaranteed that upon exception no-one can see the value. Or if such rewrite is impossible, I would make sure that the object referred to by reference `x` is destroyed before any catch-handler tries to stop the stack unwinding.
Good in principle, but this just moves the problem to the caller. Either the caller initialises a new variable to call f(), in which case things are fine -- the return value is never visible. Or the caller assigns an existing variable to call f(), in which case you're back to (almost) the original code. (Granted it will be a copy-construction plus move-assignment instead of a single copy-assignment, but that may not be better.) Despite some people talking recently about assignment being evil, it's a very important part of the language. Otherwise we'd all be using functional languages.