C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::value_or

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Tue, 15 Nov 2022 22:36:57 +0000
On Tue, 15 Nov 2022 at 20:51, Roberto R via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Hi All
>
> About the main concern in my proposal "value_or does too much". When I was
> implementing it, I made to myself the same question. Clearly if I have sent
> this proposal I arrived at the conclusion: "no", because when I start to
> implement it, I realized that it is not something so complicated.
> The weak_pointer is the case that I am not 100% sure, even in the
> definition
> of the concepts it requires a special part.
>
> @Eric your proposal of value_or is very similar to mine, just removed the
> argument pack and exposing the implementation with the contained_value
> overloadings, if you look my implementation
> (
> https://github.com/roroberto/cpp_small_simple_stupid_stuff/blob/main/value_
> or/value_or/value_or.h
> <https://github.com/roroberto/cpp_small_simple_stupid_stuff/blob/main/value_or/value_or/value_or.h>)
> in github you will see that I did something very
> similar: all the different cases are managed using simple specialized
> versions of the same function, I just kept the implementation "hidden".
>
> To expose the implementation will have the advantage to allow to extend
> value_or with other special cases, but the side effect is to expose the
> implementation therefore I am not sure about it.
>
> @Giuseppe last year I proposed a version of value_or without the support of
> invocable arguments, one of the critics was "I cannot define a default
> parameter that is a function that can be called, I can only pass a value".
> I
> started to think: "is it confusing if an invocable is passed?". If I write
> value_or(10, f), to work f must be or a pointer to an int or an invocable
> that returns a pointer to int. A pointer to a function is not convertible
> to
> an int, therefore it makes sense only if it is invoked. Therefore it is
> clear what value_or can do if f is invocable: to invoke it.
>

After p0798, shouldn't that be spelled `or_else`?


>
> Best Regards
> Roberto
>
>
>
>
> -----Original Message-----
> From: Std-Proposals <std-proposals-bounces_at_[hidden]> On Behalf Of
> Eric Schmidt via Std-Proposals
> Sent: Tuesday 15 November 2022 08:11
> To: Std-Proposals <std-proposals_at_[hidden]>
> Cc: Eric Schmidt <eric41293_at_[hidden]>
> Subject: Re: [std-proposals] std::value_or
>
> On 11/14/22 6:25 PM, Giuseppe D'Angelo via Std-Proposals wrote:
> > Hi,
> >
> > Il 13/11/22 14:27, Roberto R via Std-Proposals ha scritto:
> >> In attachment you can find a draft proposal of a function
> >> std::value_or, similar to std::optional::value_or.
> >>
> >> In previous threads I called it coalesce.
> >>
> >> Can you please tell me your opinion?
> >>
> >
> > I'm very confused by the idea that one allows both "plain values" as
> > well as callables that return values to check.
> >
> > If I call value_or with a bunch of function pointers, trying to find
> > the first non-null pointer (or return the given default), is it going
> > to try to *call* these pointers because they're callables?
> >
> > To me, the "mere" selection facility vs. try to invoke and use the
> > return values ought to be spelled _very_ differently. For instance,
> > for optional there's value_or (that takes a value) and the proposed
> > value_or_else that takes a callable.
>
> I agree with this, and would add that the proposed std::value_or is trying
> to do too much. There are special cases for std::function, std::weak_ptr,
> and std::nullptr_t.
>
> Rather than building lots of cases into std::value_or, I think it would be
> better to have a customization point that determines whether there is a
> contained value, and if so what it is.
>
> I'm thinking along the lines of
>
> template<class T, class U>
> T value_or(T&& default_value, U&& to_test) {
> decltype(auto) value = contained_value(std::forward<U&&>(to_test));
> return value ? *value : std::forward<T&&>(default_value); }
>
> when there is a single test value.
>
> And then we can write functions like
>
> // Generic case
> // Works for optional, pointers, unique_ptr, shared_ptr template<class T>
> T&& contained_value(T&& item) {
> return std::forward<T&&>(item);
> }
>
> // Special cases
>
> int* contained_value(nullptr_t)
> {
> return nullptr;
> }
>
> template<class T>
> std::optional<T> contained_value(const std::weak_ptr<T>& item) {
> auto p = item.lock();
> if (p)
> return *p;
> else
> return std::nullopt;
> }
>
> template<class T>
> std::optional<T> contained_value(std::weak_ptr<T>& item) {
> return contained_value(std::as_const(item));
> }
>
> (For weak_ptr, if you don't want a copy of the T, you can pass
> item.lock() to value_or.)
>
> --
> Eric Schmidt
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2022-11-15 22:37:09