Andrzej Krzemienski wrote:
// *operator->()
T& operator() & noexcept; T const& operator() const & noexcept; T&& operator() && noexcept; T const&& operator() const && noexcept;
This is operator*, right? This is technically narrow, but without essential benefits of direct narrow contract, as I tried to explain in another thread. I disagree.
What essential benefits are lost?
I tried to outline my reasoning in this post: http://boost.2283326.n4.nabble.com/outcome-narrow-contract-wide-contract-and...
In short, when the narrow contract is directly in the library's interface, I have a place where I can put BOOST_ASSERT(), or similar code for assisting instrumented builds.
That's what I was thinking - that you want to place an assert there - I just wanted to confirm that this is the only objection. Do we agree that returning nullptr from operator-> is good for informing the static analyzer and the optimizer that a value is present? result<X> r; // ... r->x; // same as __builtin_assume( has_value() ) X x = *r; // ditto I can understand the desire to assert() inside, but at the same time, view the idea of returning a X* to something that is not an X as monumentally misguided in an error handling library. The goal here is to help people write robust code, not introduce subtle bugs and security vulnerabilities by allowing them scribble all over the stack. (Note that with the above spec, you can still assert in op* and it would be conforming, and you can still have a mode in which you assert in op->, but it will not conform.) The root of our disagreement is the idea that undefined behavior is good because it supposedly allows you to do this or that. It isn't, it never is. Defining the good things that we want to happen is good. Not defining them in the hope they'll occur is not.