First of all, I don't agree with the strong (conceptual) relationship between optional (be it boost:: or std::experimental) in such a way that expected is a generalization of it. From what I understand, the purpose of expected/outcome/ result is to be used as a mechanism to return the result of a function. As such it should also expose the semantics of it. Fortunately, we already have a (asynchronous) return object standardized (std::future). And this is my basic disagreement here: Why not model expected in the lines of future? With the main points being:
An earlier edition of Outcome did implement future-promise. I think you yourself reviewed it then.
- expected being movable only - expected
::value() should always return by value and invalidate this.
As I mentioned in a reply to Peter yesterday, I am attracted to these semantics.
Second, I think Niall raised a valid about outcome being a framework for interoperability (completely orthogonal to the first point). However, I totally miss this from the proposed library, most pressing are non intrusive mechanisms. For that purpose I postulate, that a mechanism to transform between different unexpected results, that is: various error codes etc. However, for that to work, one would of course need a properly defined concept, for example, as Vicente suggested "EitherValue", and a mechanism to coerce one error type into another, maybe through ADL, or traits specialization or whatever.
Furthermore, I believe that .value/.error should really have a narrow contract, that is that it is UB to call those functions if the respective types are not held (easy to catch this in a debug build...). Why? Probably just a micro optimization, but consider the canonical usage: auto r = some_function_returning_expected(...); if (r.has_value()) // Do something with the value else // An error occurred, PANIC In both branches, we know exactly what's in there ... so why check again when getting the state out?
If you've already checked by hand, the compiler will elide the internal check entirely.
I don't get the "reinterpret_cast" argument. I am one of the persons that believe that UB is a necessary evil for some optimizations...
I am not keen on sprinkling reinterpret_cast everywhere. But it appears
When I open its "landing page", I get no idea about the following: - What is the purpose of the library? - Why/when should I use it?
It quite literally tells you both on the landing page. https://ned14.github.io/boost.outcome/index.html. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/