C++ Logo

std-proposals

Advanced search

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

From: Chris Gary <cgary512_at_[hidden]>
Date: Thu, 2 Nov 2023 10:29:28 -0600
>
> Implicit conversions are the root of much evil in C++.
>
So is all the bikeshedding about primitives meant to protect misuse of what
ultimately becomes a raw pointer.
In this case, make that about what brand of styrene to use for a scale
model bikeshed to be situated on a molehill.
Its a trivial new addition. Use it or don't.
Would it help users that follow this convention? Yes.
Will it break existing code? No, since it isn't done with standard
containers yet.
Worried about running into code you don't like? Blog about it (no offense).

I really wish more users would start learning with C, then treat this as "C
with classes and a nifty type algebra".

On Thu, Nov 2, 2023 at 9:59 AM Arthur O'Dwyer via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Ville, I think you've temporarily forgotten the mess that is
> `optional<bool>`.
> "Empty" (as in "it's a range of zero elements, i.e. its value is the empty
> sequence") and "disengaged" (as in "it has no value") are two different
> concepts; and both are fundamentally different from "falsey" (as in "its
> value is boolean false").
> Implicit conversions are the root of much evil in C++.
>
> On Thu, Nov 2, 2023 at 11:10 AM Ville Voutilainen via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>>
>> A call to an overload set that deals with ranges or singular values. Thus:
>>
>> template<class T, class F> void checked_process_it(T&& t)
>> {
>> if (t)
>> process_it(std::forward<T>(t));
>> else
>> nag("hey, don't do that");
>> }
>>
>
> I think what the programmer meant here was more like:
> if constexpr (!std::ranges::range<T>) {
> process_it(std::views::single(std::forward<T>(t)));
> } else {
> process_it(t);
> }
> Obviously if `process_it` expects a ranges::range, it has to be prepared
> to deal with the possibility that the range is empty (even if the way
> it deals with that is just to say `if (ranges::empty(rg)) nag()`), since
> ranges *can* be empty.
> checked_process_it(std::vector<int>{}); // original code nags
> checked_process_it(std::make_optional(std::vector<int>{})); //
> original code fails to nag
> Furthermore, if `checked_process_it` really intends to deal with
> optionals, (smart) pointers, etc., then it is probably missing some code to
> unwrap the optional/pointer after checking it for engagement/non-nullness.
> That is, instead of
> if (t)
> process_it(t);
> the programmer probably meant
> if (t.has_value())
> process_it(t.value()); // not just `t`!
> and/or
> if (t != nullptr)
> process_it(*t); // not just `t`!
>
>
> I can put it into a refined range concept that has the ability to
>> check emptiness, though.
>> And this really sounds like a bug in ranges that could be entertained
>> to be fixed retroactively,
>> even if that causes a little breakage. It's quite odd if a generic
>> view that can be as lazy as imaginable
>> can provide an empty() but a generic range can't.
>>
>
> FYI, some input ranges can't provide .empty().
> The C++20 Ranges library solution is to provide a* free function* (well,
> CPO) `ranges::empty` and tell people to use it instead. Ranges provides all
> these "generic" primitive functions through CPOs instead of member
> functions; that's just its style, for better and worse.
>
> –Arthur
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2023-11-02 16:29:37