
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@yahoo.com> 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