On 17/05/2017 11:34, Peter Dimov wrote:
So why not "T get()"? That's much more consistent with other types.
.get() is when you only have one thing to get; it's for one-element containers, where there's no ambiguity as to what is being got.
expected
and friends have two; the value is .value() and the error is .error(), with their matching queries has_value() and has_error().
But by definition these are not treated equally. The value is the expected thing (thus get() makes sense to retrieve it) and the error or exception are the unexpected things (thus some other method). I don't see any ambiguity there.
It's not that get() is unacceptably wrong, but the value/has_value/error/has_error convention is legitimate and consistent.
Having "T value()" as the only API is fine, but seems a bit inconsistent as that's not the common verb used by other types (in fact it's not even a verb). (std::get is another argument in favour of this.) Having "T value()" and "T get()" is ok (it's sort of like Boost Optional that way) but it's a bit redundant and it would just make people second-guess which one they should use, or if they're different in some way. Having "T value()" and "void get()" is just bananas. Though for Niall's proposed usage, perhaps "void ensure()" would make sense. Regarding [[nodiscard]], I don't think either of these methods should have that. Instead it should be the method that returns the expected<> or outcome<> that declares its return value to be [[nodiscard]] (if it wishes). Though I recall another proposed library using some trick (possibly involving rvalue-methods?) to ensure a compiler error if the return value was uninspected without explicitly using [[nodiscard]].