Le 24/05/2017 à 17:31, Niall Douglas via Boost a écrit :
Back at the beginning when designing Outcome, one of my design ideas was > a variety which called std::terminate on destruction if an error had > never been retrieved. So, the idea behind this family of Outcomes was > that they were "single shot", .error() and .value() could be called > exactly once after which the outcome became empty. On destruction, if an > error had never been retrieved, it was fatal exit time. I wouldn't go as far as calling terminate(), but one could log. I'd make what happens user definable of course, but the default implementation would be std::terminate. After all, these be rigorous Outcomes, failure to collect state is a logic error - it equals "your code is wrong". I don't think we should manage this with complex implementation. We should use attributes and static analysis.
But for this to work, the outcome must be noncopyable (move-only). Otherwise if you make a few copies, none of it could know whether you inspected the error of some of the other copies or not. I had been thinking of copy constructor disabled, but there would be a clone() member function. You see. Managing this kind of possible issues make the implementation more complex than necessary. E.g. Would you remove new because the user could not store it in a variable and delete it later on?
This doesn't require an empty state though, just a bit that is set (or maybe cleared) when error() is called. I think the source of our disagreement is over publicly exposing the empty state. You appear to be happy if it's an internal only thing, but not available to end users. I take the view that if you're implementing the empty state anyway, might as well open it up for public use.
Can you give a reason why public availability of an empty state with well defined semantics and behaviours is a bad idea? Does it naturally lead to incorrect code or something?
Because it makes the user code more complex. This is the task of static analizers. We have a lot of examples maintaining publicly this empty state because the cost of ensuring this empty (partial state) is not expensive. We have it with unique_ptr, exception_ptr. However, how many lines of code have you seen that checks for whether exception_ptr contains an exception or not? Anyway, I have not understood yet when we need this empty state on the implementation and les yet when does the user needs it. I'll persevere. Vicente