C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Bool casting operator to check if a container not empty

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Thu, 2 Nov 2023 10:28:04 -0400
On Thu, Nov 2, 2023 at 10:04 AM Ville Voutilainen via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> On Thu, 2 Nov 2023 at 15:53, Edward Catmur via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
> >
> >
> >
> > On Thu, 2 Nov 2023 at 07:53, Chris Gary via Std-Proposals <std-proposals_at_[hidden]> wrote:
> >>>
> >>> .... Just because you *can* collapse some property of containers to a simple true/false, doesn't mean we should add a conversion to actually do that.
> >>
> >>
> >> Its concise if used in conjunction with the Elvis operator:
> >> populateWith( oneVec ?: orAnother )
> >> printLine( errMsg ?: g_successMsg ) // these could be string_view or string
> >>
> >>> The whole if ("") vs. if (""sv) is a complete red herring - those
> >>> don't appear in any generic context, and in fact those don't appear
> >>> anywhere.
> >>> Nobody writes that. Nobody is confused by it.
> >>
> >>
> >> Seconding this.
> >
> >
> > I would dispute that; we use std::string_view() (i.e. std::string_view(nullptr, 0)) as a sentinel value, distinct from ""sv. Indeed, we would regard ""sv as truthy, since it is engaged in the sense that its data() is non-null. (The same holds for std::span, of course).
>
> How does that dispute anything?
>
> Do you write if (""sv) somewhere?
>
> > If you really want contextual conversion to bool, wrap in a type that has that conversion. C++ is the land of zero-overhead, after all. And in generic code, use std::ranges::empty().
>
> Which doesn't work for non-ranges like pointers and optionals. If
> there's an actual generic way to check that something has a value in
> it,
> be it singular or plural, you can write a generic check, and handle
> the singular/plural difference elsewhere, in slightly less generic
> generic
> code. ranges::empty() isn't that generic check.

It is for ranges.

What kind of generic code are you operating in where you have some
unknown `T` that could be a pointer, optional, or range, *and* you
need to know if it is "empty"?

You test a pointer or optional to see if you can dereference it. You
cannot dereference a range. So what code exactly is going on inside
this hypothetical `if` statement?

> The point of
> suggesting that containers could be bool-checked is that a contextual
> conversion
> to bool would be that generic check.

Which will not work for arbitrary ranges because `std::ranges::range`
does not have a bool-check as part of its constraints. So this would
only be a generic check for containers and maybe views, not all
ranges.

So what kind of generic code are you writing where it is OK for it to
work on views and containers but not for any `range` type? You can't
backport this into `range`, after all, as this would break a ton of
code.

Received on 2023-11-02 14:28:44