C++ Logo

std-proposals

Advanced search

[std-proposals] optional<T&> semantics [was Re: inplace_vector failable apis]

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Wed, 22 Nov 2023 18:50:00 +0000
On Wed, 22 Nov 2023 at 18:31, Jason McKesson via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> On Wed, Nov 22, 2023 at 11:25 AM Barry Revzin via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
> >
> >
> >
> > On Wed, Nov 22, 2023, 9:03 AM Tony V E via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
> >>
> >> I have implemented it.
> >>
> >> It just isn't used that much. So no real implementation experience
> either way. It hasn't been a problem, but neither optional<T&> nor
> assignment come up that much at all, so inconclusive.
> >
> >
> >
> > Disagree. optional<T&> comes up quite a bit. And we use it a lot. I
> don't understand where the claim comes from - it's clearly used.
> >
> >>
> >> If anything, I'd say
> >>
> >> Imagine that vector.front() returns an optional<T&>...
> >>
> >> As the developer writing vector, I'd like assignment to rebind.
> >> As the developer using vector.front(), I'd like assignment to not
> rebind.
> >>
> >> auto f = vector.front();
> >> if (f)
> >> f = 17; // current optional would not be able to assign from an
> rvalue
> >>
> >> But again, totally inconclusive.
> >
> >
> > Disagree again. If you want to assign through, there's syntax for that:
> *f = 17. This is the same thing you would write if front() returned a T*
> instead. It's the most reasonable choice too - if you want to operate in
> the T&, you pull out the T& and operate on that. Same as you would for any
> other type. optional<T&> is an optional, so it behaves like an optional -
> it's not literally a reference.
> >
> > Muddling the semantics of assignment to save a single character of
> syntax in this case doesn't seem like a great tradeoff.
>
> So what you're saying is that this is fine:
>
> ```
> T t = value;
> t = other_value; //Assign-through to the object named by `t`.
>

This doesn't assign "through" anything, it assigns to t. There's no
"through" so your entire premise is shaky.


>
> optional<T> t = value;
> t = other_value; //Assign-through to the `T` in `t`.
>


I don't think this assigns "through" either. It gives a new value to
t.value().

I prefer to think of that operation as an optimization for:

t = optional<T>(other_value);

And that could be implemented in terms of destroying t.value() and creating
a new value, but for efficiency we reuse the existing value (if present)
and assign to it instead. But semantically, it's creating a new optional<T>
from other_value and changing t to have that value.


> T &t = object;
> t = other_value; //Assign through to the object referenced by `t`.
>
> optional<T&> t = object;
> t = other_value; //Not assign-through.
> ```
>

Assuming a rebinding optional<T&>, that can also be seen as:

t = optional<T&>(other_value);

I don't see this as inconsistent with optional<T>. The difference is that
we can't "reuse" the existing reference, because references are immutable
once created. Assigning through the reference would not be the same as
copying optional<T&>(other_value) because it would mutate the referent. So
the "reuse the existing object" optimization from optional<T> doesn't make
sense here. To implement the "create a new optional and change to to have
that value" semantics requires rebinding.



>
> This is one of the few places in the language where a language
> reference is treated as a distinct concept from the object it is
> referencing. References to objects are assign-through. Optional
> objects are assign-through. Optional references-to-objects are not
> assign-through.
>
>
References are weird. But optional<T&> is not a reference, it's an object.
It's not supposed to *be* a reference, or behave exactly like a reference,
it's supposed to *contain* a reference (or not contain one when empty).



> And that's supposed to make sense.
>


Well I don't think your description of the semantics of your example makes
sense. You're using the term "assign through" where it doesn't make sense,
and then pointing out how that leads to confusion. Don't do that then.

Received on 2023-11-22 18:50:15