C++ Logo


Advanced search

Re: nullptr_t and nullopt_t should both have operator<=> and operator== to enable the *_with concepts

From: Justin Bassett <jbassett271_at_[hidden]>
Date: Sun, 11 Jul 2021 21:17:51 -0700
Hi Jens,

I've been thinking through your comments on the Tony Table.

For the remove_nulls, I agree that range_value_t<R> is a better solution,
but I didn't write that in the Tony Table for two reasons:

   1. In some functions' contexts, perhaps with a private unconstrained
   function template, there is no solid guarantee that the range is of
   optional<T>, so I was trying to capture that sometimes remove_if becomes
   the cleanest solution.
   2. range_value_t<R>() or range_value_t<R>(nullopt) are both more
   "complex". I personally have to pause during reading to figure out what
   it's doing, whereas reading the remove_if is easy for me, and I was
   assuming that the average developers---not C++ standard committee
   members---would probably have a similar response.

I suppose what I'm saying is that even if it's not best practice, I would
still expect the remove_if to appear quite often in code, probably after
the author was left wondering, "Why can't I just pass in nullopt?". I tend
to agree with you that this Tony Table doesn't provide exceedingly strong
motivation for this proposal, as we can always use optional<T>() (or
computed type name) or smart_ptr<T>() to quite cheaply get the same
behavior, but I have yet to be able to come up with better entries.


On Sat, Jul 10, 2021 at 12:53 AM Jens Maurer via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> On 10/07/2021 09.18, Justin Bassett via Std-Proposals wrote:
> > I attempted to address these issues in the attached updated draft. It
> adds many more diffs to the Tony Table, talks about N2478, briefly
> discusses the odd nature of requiring equality_comparable<U> for
> equality_comparable_with<T, U>, and includes a few minor changes (adding
> SG9, uses a hidden friend for the defaulted operator<=>, borrows the
> wording prior to N2478 for nullptr comparisons).
> >
> > On the Tony Tables: it turns out that without the templates, many of the
> examples are trivially fixed by converting nullopt -> std::optional<int>()
> or nullptr -> std::shared_ptr<int>(). With templates, suddenly the
> information of precisely what optional or what smart_ptr was used becomes
> hidden, so we have to spend effort to recover that information. So the
> templates in fact show some cases with a bigger impact. However, even
> without the templates, it can turn out to be more readable to use the
> nullfoo variants instead of default constructed types.
> What does "alternative is enabled" mean?
> In your Tony Table for remove_nulls(nullopt), you assert
> that you have a range of optionals. The lambda passed to
> ranges::remove_if can thus be cleanly replaced by
> ranges::range_value_t<R>() (which ends up as optional<T>()).
> Using this formulation makes the algorithm actually apply
> for both smart pointer and optional uses, because the
> funny nullopt vs. nullptr in the body has been eliminated.
> In short, I don't feel the Tony Tables adequately represent
> the best practice in formulating those algorithms, either
> "before" or "after". Given that, the "odd" behavior of
> nullptr and nullopt is maybe actually good, because it forces
> you to write better code for these generic situations.
> Please rebase onto the newest working draft, https://wg21.link/std
> (This might just be an exercise in updating the references.)
> Thanks,
> Jens
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2021-07-11 23:18:10