
2017-05-30 16:01 GMT+02:00 Dominique Devienne via Boost < boost@lists.boost.org>:
On Tue, May 30, 2017 at 3:51 PM, Niall Douglas via Boost < boost@lists.boost.org> wrote:
On 30/05/2017 13:25, Peter Dimov via Boost wrote:
Niall Douglas wrote: There is a middle ground here, which I was pondering for a while, make has_value return T* instead of bool.
It's a clever idea, but it reminds me too much of C++ 98 days of returning void * and such to implement boolean testing. We all got badly bitten with those tricks
But that was mostly from implicit conversions though, while here it's an explicit method call.
My concern is more that I expect a has_value() method to return a boolean, not a pointer. value_if() OTOH is elegant, almost self-explanatory, and the if(auto* p = o.value_if()) idiom is quite readable, despite the two ifs. FWIW. --DD
Another name for the function could be `try_value`. But I can still see one use case, where it feels strange. I have just created an `expected` containing a value. Now I want to refer to it directly: ``` expected<vector<T>> mahe_vec() { expected<vector<T>> ans {value}; // creates an empty vector in-place vector<T> & vec = ans.value(); // ... } ``` Niall has indicated a number of times that the second defensive if is removed in context like the following: ``` if (ans.has_value()) ans.value(); // second check elided ``` But in my case with `vector` there is no first check, but I am still sure the value is there because I can trace the entire (quite triviall) life-time of the object. Using value_if is possible, but: ``` expected<vector<T>> mahe_vec() { expected<vector<T>> ans {value}; // creates an empty vector in-place vector<T> & vec = *ans->value_if(); // ... } ``` It doesn't indicate what I am doing clearly enough. If I had a narrow-contract accessor, it would read clearer: ``` expected<vector<T>> mahe_vec() { expected<vector<T>> ans {value}; // creates an empty vector in-place vector<T> & vec = ans.just_value(); // ... } ``` Returning a pointer actually only superficially looks like you are protecting yourself from the narrow contract. You just force the caller to use narrow contract function on the pointer. This reminds me that at some point people here in Boost discussed that get<T>() accessor on variant<T, U, V> should return optional<T&>. Regards, &rzej;