Subject: Re: [std-proposals] P0323 std::expected - void value type?
From: Dusan Jovanovic (DBJ) (dbj_at_[hidden])
Date: 2020-10-05 00:41:31
P2192 does not tell you what should not make sense for you, what is "really
hard" or how you need to become and stay "more in keeping with existing
paradigms". The next step in that direction would probably be to "advise"
your customer not to ask for no exceptions, I guess.
On Mon, 5 Oct 2020 at 02:26, Jason McKesson via Std-Proposals <
> On Sun, Oct 4, 2020 at 5:21 PM Emile Cormier via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
> > Hi Everyone. This is my first time posting to this group, so please be
> gentle. :-)
> > I'm in need of a value-or-error mechanism for a C++11 library I'm
> working on, where I don't want to impose exceptions to the client. Having
> completed a toy "result<T, E>" implementation inspired by std::expected, I
> decided to implement a complete C++11-ized version of the P0323R9 proposal.
> > I am questioning the rationale of allowing void as a value type for
> std::expected. As I understand it, expected is supposed to be a "vocabulary
> type" similar to std::optional, or std::variant, yet the latter two don't
> permit void as one of their contained types (as far as I know).
> Functions that don't return a value still need to be able to inform
> the caller whether or not an error has taken place. You could just
> return the Error type directly, but this requires that the Error type
> be able to also signal the *lack* of an error. And while lots and lots
> of basic error code types are designed that way, we shouldn't
> *require* it at an interface level.
> You could return an `optional<Error>`, but `optional` doesn't have the
> same machinery or interface as `expected`. If you want to propagate
> the Error given to you through your own `expected` return value for
> example, you can use `return unexpected(...)`, which is convertible to
> any `expected<T, Error>`. You don't have that mechanism in `optional`,
> and you probably shouldn't.
> It's easier to write template code that can handle errors when you're
> using a single return type with a single, well-understood interface.
> Now, the question you're really asking is why `void` specifically is
> used. Yes, using `void` for this (because of its incompleteness) does
> complicate implementations. Fortunately, C++20 concepts can alleviate
> a good deal of this complexity (or at least minimize it).
> The alternative is to create a type that explicitly means "no value".
> But `void` is a natural type to mean "no value". Indeed, it's already
> a part of `std::promise/future`; if you want to just signal the
> competition of a task (or transmit an exception, you can use
> `future<void>`. I imagine that wasn't exactly easy to implement.
> The reason this was done for `variant` is that it is *really* hard to
> implement a `variant` that takes `void` members. You don't just have
> to handle one case; you have to handle each case in each position. It
> becomes prohibitively expensive after a while. So using a special type
> to mean "no value" makes sense.
> And it doesn't make sense for `optional` to allow any kind of "no
> value" type. You can't have a NothingOrNothing type ;)
> So while it does cause some implementation burden, I'd argue that it's
> more in keeping with existing paradigms (particularly with
> `promise/future`) to just use `void`.
> Std-Proposals mailing list
STD-PROPOSALS list run by firstname.lastname@example.org
Standard Proposals Archives on Google Groups