Date: Thu, 2 Nov 2023 18:23:21 +0200
On Thu, 2 Nov 2023 at 18:18, Edward Catmur <ecatmur_at_[hidden]> wrote:
>> > 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.
Thanks, that explains things.
>> > 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.
No, I don't - because that generic code can separately deal with that
difference.
>> 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
No, I don't necessarily surely intend that, because that access may be
elsewhere.
>> 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.
Right, so it does mean "contains a value", because like a non-empty
container, you can walk it and get values out of it.
>> 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?
What of them? We could easily give them a well-formed and well-defined
emptiness query that is always false. I don't see how that's
an obstacle of any kind.
>> > 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.
Thanks, that explains things.
>> > 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.
No, I don't - because that generic code can separately deal with that
difference.
>> 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
No, I don't necessarily surely intend that, because that access may be
elsewhere.
>> 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.
Right, so it does mean "contains a value", because like a non-empty
container, you can walk it and get values out of it.
>> 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?
What of them? We could easily give them a well-formed and well-defined
emptiness query that is always false. I don't see how that's
an obstacle of any kind.
Received on 2023-11-02 16:23:35