Subject: Re: [std-proposals] P0323 std::expected - void value type?
From: Arthur O'Dwyer (arthur.j.odwyer_at_[hidden])
Date: 2020-10-04 21:27:28
On Sun, Oct 4, 2020 at 5:21 PM Emile Cormier via Std-Proposals <
> Hi Everyone. This is my first time posting to this group, so please be
> gentle. :-) [...]
> 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).
Right, but std::future/std::promise do.
The idea behind future<void> is that we want to be able to write
auto async(auto f) -> std::future<decltype(f())>;
without worrying about some special case when f() is void, or when f()
returns a reference type. We want it to *just work* with any return-able
Similarly, expected<T,E> is at least arguably supposed to be used as a
auto probably_but_not_certainly(auto f) -> std::expected<decltype(f()),
So it makes sense for it to support all return-able types.
"But what about optional<T>?" you say, rightfully.
auto maybe(auto f) -> std::optional<decltype(f)>; // not generic
You can't use this `maybe` on callables that return void, nor on callables
that return references. Why not? Well, definitely an artifact of the
standardization process. I would say that std::optional was trying to serve
two masters. On the one hand it's trying to be a generic utility type, but
it's also looking up to its big brother std::tuple, which *itself *was
serving two masters -- std::make_tuple/std::forward_as_tuple on the one hand
and std::tie on the other. So it became unclear whether std::optional<U&>
should have copy semantics like std::reference_wrapper<U>, or
assign-through semantics like std::tuple<U&>. JeanHeyd Meneide has a blog
post from January 2020 on the subject:
STD-PROPOSALS list run by email@example.com
Standard Proposals Archives on Google Groups