From: Fernando Cacciola (fernando_cacciola_at_[hidden])
Date: 2005-10-18 09:24:04
Sam Partington wrote:
> Hi there,
> Firstly whilst reviewing this thread and the optional docs I spotted a
> couple of minor typos :
> "(Re)binds thee wrapped reference." : thee -> the
> "untitialized" -> uninitialized
> In the In-place factory discussion, the last code segment has been
> corrupted slightly : template<class inplacefactory=""></class>
> should presumably be :
> template<class InPlaceFactory>
> Also, whilst the docs I think in general are good, I find some of the
> acronyms used in the docs slightly too informal for formal
> documentation, for instance IMO and w.r.t.. Whilst they are well
> known, it does cause the brain to stall momentarily whilst trying to
> understand some quite difficult concepts.
> Now, onto the discussion at hand.
> I must admit I find the whole rebinding interface very ambiguous.
Just to keep the discussion clear, is a matter of semantics not interface.
> What we have is a reference that is potentially null.
> In my mind that is a pointer (wrapped up obviously),
> and not an optional at all.
Maybe you meant "not a reference at all"?
Well, in optional<> this is implemented as a true reference, not as a
pointer like in reference_wrapper().
So is more like that there is a reference or nothing.
> I use a class called ref_ptr<> for that purpose, and it has served me
> well - A smart pointer with no ownership.
> That this discussion is going on so long and is so disputed it seems
> to me that there is no right-way, and the best way of fixing it is to
> disallow T& altogether.
This is one choice, yes.
I hope we can solve it because dorpping T& totally breaks generic
> But if it were to stay I would say that the rebinding is very
> surpising for someone used to using references.
And so is the no-rebinding alternative.
Look for _my_ thought experiment in another pos.
Do it yourself, show it to your mate, and share with me the results.
> In the rationale the first example states "If you assign to an
> uninitialized optional<T&> the effect is to bind (for the first time)
> to the object. Clearly, there is no other choice".
> Remove the operator=(const T&)
Yes, this could also work.
Initially I was against such operator, but for the wrong reasons, so in the
end I accepted it.
> int i = 0;
> optional< int & > o(i);
> int n = 0;
> *o = i; // assigns new value
> o = optional<int&>(i); // rebinds, nice and explicitly
The problem which was raised is that it adds an unnecesary verbosity.
That is, why can't you define:
o = val ;
as a convenient shortcut for:
o = optional<T>(val);
All by itself, is looks quite reasonable.
Now you brought this issue back but into the context of optional references.
Is it totally clear to everyone that this rebinds?
o = optional<int&>(i);
Joel de Guzman said that he wouldn't be against rebinding in this case. He's
against rebinding in the direct-assignment case, so simply dropping
direct-assignment is definitely a way out, even at the cost of dropping some
One could say: optional does not support a convenient direct assignment
operator becasue it could hide the true semantics of the assignment, which
are clear if only assignment from another optional is used. (Followed by an
A related note about the use of operator *
You said that, even for optional<T&>, it is clear that this:
*o = i;
is UB if 'o' is uninitialized. And so there is no problem defining that
assignment as really just the assignment of the underlying type, which in
the case of optional<T&> doesn't rebind.
Now I wonder, if instead of operator*, we used value() (or whatever), would
it be just as clear?
int a = 1 ;
int b = 2 ;
int c = 3 ;
int& ra = a ;
int& rb = b ;
int& rc = c ;
optional<int&> o(ra) ; // binds to a
// Nullable interface
*o = rb ; // assing 'b' to 'a'
o = none ; // releases 'a'
*o = rc ; // !!! UB !!! Cleary IMO
// Container interface
o.value() = rb ; // assing 'b' to 'a'
o.reset() ; // releases 'a'
o.value() = rc ; // !!! Still UB !!! ¿But cleary enough?
-- Fernando Cacciola SciSoft http://fcacciola.50webs.com/
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk