Boost logo

Boost :

From: Yuval Ronen (ronen_yuval_at_[hidden])
Date: 2005-10-18 15:21:30


Hi.
I'm an optional<> user, and a big fan of it. I'm also unable to resist
my temptation of expressing my opinion... :-)

Fernando Cacciola wrote:
> David Abrahams wrote:
>
>>Anthony Williams <anthony_w.geo_at_[hidden]> writes:
>>
>>
>>>How's this for a radical thought --- optional<T> should not be
>>>assignable from T. That way, it doesn't matter whether T is a
>>>reference, or not.
>>
>>There's at least some precedent for types that are "immutable except
>>for copy assignment."
>>
>>The assignment from T is really a kind of mutating operation.
>>
>
> Indeed.
> I'm leaning fast into dropping assignment form T.
> That definitely solves the reference binding issues.

If that means that I'll have to write

o = optional<T>(x);

then I vote against. This is ugly...

> Antony's proposal goes even beyond Sam's idea: rather than dropping
> assignment from T, we spell it: reset().
> That is definetly better then direct assignment from T, but I'm not quite
> sure that is as good a solution as keeping just copy assignment.
>
> Consider these 3 versions:
>
> int a = 1;
> int b = 2;
> int& ra = a ;
> int& rb = b ;
>
> optional<int&> o(ra);
>
> *o = rb ; // Clearly doesn't rebind but is UB if 'o' were null.
>
> // (1) Current case:
> o = rb ; // rebind or not??
>
> // (2) Antonty's proposal:
> o.reset(rb); // still some room for doubts?

Plently of room for doubts. Actually, why calling it reset() makes it
any different from an assignment operator? This is just the same, and
the old "to rebind or not to rebind" question comes back, this time with
respect to the reset() method.

> // (3) Sam's proposal:
> o = make_optional(rb); // Clearly rebinds, doesn't it?
>
> // I just introduced make_optional() here to get rid of the template
> argument

Oh, this is much better than the

o = optional<int&>(rb)

I just voted againts, but is it feasible? Can make_optional() know if it
should make an optional<T> or optional<T&>? Perhaps a way can be found,
but I'm not sure of it.

In a more general context, I have to say that I've never used
optional<T&>. Whenever I need to have an optional reference I use a
pointer. So I tend to think of optional<T&> in terms of T*. This is why
when the question first came up, I was in favour of rebinding - to do
just as T* does. Then (after reading one of the posts in this thread) I
thought that the same facts can lead me to the very opposite conclusion:
if I can always use a plain T* for rebinding semantics, then
optional<T&> can be left for the other use cases - i.e. no rebind.

Anyway, as I said, I've never used optional<T&>, and I'm willing to let
go of it completely, especially if it can save direct assignment from
T... And even more especially if it will help my favourite library be
accepted into the standard... ;-)

Just one more thing: I feel the example shown by Peter Dimov was not
properly addressed. In my words, a variant and an optional are very
similar in a way that they both might be creating a previously absent
object, as a result of an assignment operator. Both optional<T&> and
variant<T&, ...> may or may not contain a T& object at a given moment,
and thus should behave the same on assignment. May that behaviour be
rebind or no-rebind, it should be applied to both. It's a pity that
variant seems to be neglected recently (it might need repairs after a
conclusion is reached)... Tuple, on the other hand, doesn't suffer from
this issue, so I don't think it's a part of this debate.

I hope I contributed something to the discussion,
Yuval


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk