C++ Logo

std-proposals

Advanced search

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

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Thu, 2 Nov 2023 11:17:49 -0500
On Thu, 2 Nov 2023 at 09:03, Ville Voutilainen <ville.voutilainen_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?
>

We write if (sv.data()) in some situations, and if (not sv.empty()) in
others. The point is that there is no unambiguously best or most obvious
property of a string_view for contextual conversion to bool.

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


And you can't call std::ranges::begin() on those, so you need to wrap them
in a range anyway if you want to pass them to generic code.

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.


If you're trying to distinguish between emptiness and containing
one-or-more values, you must surely intend to access those values under the
scope of that check, which means that you need to adapt the something to a
range-style interface. So do that before the emptiness check instead of
after.


> The point of
> suggesting that containers could be bool-checked is that a contextual
> conversion
> to bool would be that generic check. We can certainly entertain having
> something else instead, but contextual conversions to bool are
> already idiomatic and common. We have them for iostreams, for example.
>

And that contextual conversion does *not* mean "contains a value", it means
"is not in an error state", because for iostreams good() is the most
relevant property in the majority of situations.


> We just don't have them for containers, because containers
> for some reason want to be different, and that then gets explained by
> funny corner cases with literals that nobody uses.
>
> This is also not a zero-overhead question. If you don't need that
> check, don't use it. That causes no overhead for you. The ability to
> do such
> a check for a container has no space or time overhead for those who
> don't use it, so it conforms to any zero-overhead principle perfectly
> fine.
>

It means privileging 'not empty()' over all other properties that could be
justifiably used for contextual conversion to bool. What of containers such
as array that can't even be empty?

Received on 2023-11-02 16:18:03