C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Making the converting constructor of std::optional less greedy

From: Oleksandr Pikozh <o.pikozh_at_[hidden]>
Date: Sat, 9 Dec 2023 01:06:34 +0200
On the one hand, I agree with Egor and Arthur that the proposed design
change might theoretically have sense (I don't say anything on whether it
should be done practically).

On the other hand, if I personally wrote such classes (like `MaybeInt` or
`Proxy`), I wouldn't let them be implicitly convertible to int. Instead:

1. At least, I would make the conversion-to-int operator explicit.

2. At most (and even better), I would make the int (non-optional) value
accessible via another operator (e.g. asterisk) or even a method (like
`value()`; the return type of that operator/method would be probably a
secondary proxy class). In other words, `x` itself must not be implicitly
castable to int, but `*x` may. In other words, before allowing our classes
(like `MaybeInt` or `Proxy`) to be convertible to optional, we should first
ensure that semantically they're like optionals.



On Fri, Dec 8, 2023, 18:00 Arthur O'Dwyer via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> On Thu, Dec 7, 2023 at 10:29 AM Edward Catmur via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> Another case that I think is ultimately related:
>>
>> #include <functional>
>> int main() {
>> std::copyable_function<void()> f;
>> std::move_only_function<void()> g = f;
>> if (g)
>> g(); // oops, throws std::bad_function_call (and crashes)
>> }
>>
>
> I agree that this is unfortunate — and probably should be fixed — because
> that's the entire point of putting these types into the STL: so that they
> can interoperate correctly!
>
> However #1: this really just shows that `function` should never have been
> nullable in the first place. The original sin here is using "g is truthy"
> as a proxy for "g is safe to call." The best approach is just to maintain a
> program invariant that you never branch on the truthiness of a `function` —
> if you're in a situation where you want a "maybe-a-function," you should
> just use `optional<function>` or some such. The bool conversion for
> `function` itself is a trap.
>
> However #2: the copyable_function => move_only_function conversion problem
> seems closely related to the function_ref => function conversion problem:
>
> https://quuxplusone.github.io/blog/2019/05/10/function-ref-vs-string-view/#but-consider
>
> std::function<int()> convert(std::function_ref<int()> f) { return f; }
> int main() {
> std::function<int()> f = convert([]() { return 42; });
> f(); // boom, this `function` stores a `function_ref` which is now
> dangling
> }
>
> In the function_ref case there's really nothing we can say other than
> "don't do that, then." It's the same as storing any other
> callable-containing-a-dangling-reference (e.g. most lambdas) into a
> `std::function`.
>
> –Arthur
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2023-12-08 23:06:49