C++ Logo


Advanced search

Re: [std-proposals] std::value_or

From: Eric Schmidt <eric41293_at_[hidden]>
Date: Wed, 16 Nov 2022 22:38:09 -0800
On 11/15/22 12:51 PM, roberto.romani_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) 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.

To be clear, I was not suggesting that we allow only one test value. I
wrote it that way because it was simpler and my main intent was to
convey the idea.

My concern with "doing too much" is not really about how complicated it
is to implement, but rather cleanliness of design. The specification of
value_or, as currently proposed, is complex. It would be nice for it not
to know about std::function, etc.

To address your concern about exposing implementation details, I don't
think it is much different from std::sort accepting a comparator, or (to
take something even more closely analogous) the ability to define a swap
function for your class, and thus affect the operation of std::sort.

What I am suggesting is that there is some way for user code to specify

(i) whether a test type contains a value and
(ii) what that value is.

These requirements naturally suggest std::optional, but returning a
std::optional will often require making a copy, which is not always
desirable (or possible). So I was thinking that the return type could be
either std::optional<T> or T*, as appropriate. But as I was writing the
functions I realized the return type could just be anything that
supported operator bool and operator*.

I'm not entirely happy with that way of doing it. Currently I'm not sure
what the best approach is.

(By the way, one thing I find puzzling about your paper is that it uses
operator! to test for value containment. I don't understand the reason
for this.)

> -----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

Received on 2022-11-17 06:38:46