From: Fernando Cacciola (fernando_cacciola_at_[hidden])
Date: 2003-10-31 14:11:22
Joel de Guzman wrote:
> Fernando Cacciola <fernando_cacciola_at_[hidden]> wrote:
>> "Brian McNamara" <lorgon_at_[hidden]> escribió en el mensaje
>>> do what you want? If T is a reference type, the match's constructor
>>> puts the reference in the optional, and then calls to value()
>>> change the value of the referred-to object. If T is a
>>> non-reference type, it also works, as far as I can tell.
>> Maybe the problem is genericity.
>> I guess the implementation of 'value()' cannot use the '*' syntax
>> because 'data' might be something different than an optional<>.
> Well, not really. a match always has 'optional' data. What I am
> is that a match<T> is conceptually an optional<T> and hence, the same
> reasoning to both classes must apply: i.e. the match<T> use case must
> also apply to optional<T>.
I'm being inclined to prefer your proposed semantics but, incidentally, in
spite of your use case which AFAICT simply reveals that you don't want to
use the '*' syntax, but doesn't show a 'requirement' for true reference
That is, as Brian says, you can have the semantics you want if you stick to
the '*' syntax.
This is not to say that there are no 'conceptual' reasons to prefer true
reference semantics, however.
By studing your use case I wondered why wouldn't you use the '*' syntax,
which I recommended from the beginning.
In fact, your example is actually setting a very good case in favor of '*',
let me explain:
If the lhs is uninitialized then the assignment is undefined w.r.t true
reference semantics. This is in fact exactly the same as trying to access
(read) the value of an uninitialized optional.
>From the beginning I wanted a special syntax to add lexical context to the
operations that may be undefined when uninitialized optionals were involved.
Currently, you _need_ to use '*' to access the optional value, and, if true
reference semantics are to be used, then assignment is effectively accesing
this value, so requiring '*' also for assignment looks right to me.
However, complains about the '*' syntax drawn me to assume that assignment
was always well defined so I dropped the '*' as a requirement for
assignment. But true reference semantics are actually breaking the
assumption, leaving a question open: what to do if assignment cannot happen
because the lhs optional<> is uninitialized? I realized now that if I had
sticked to the '*', the question would have the same simple answer as the
case: opt->assign(val) when opt is uninitialized: the behaviour is
Unfortunately, the current syntax options allows you to write either
"*opt=val" or "opt=val", but, by the current design, both operations must be
This last observation settles the matter of assignment semantics AFAIC,
which brings me back to the question I posted in this thread.
>> Joel, your use case seems to indicate that the required aliasing
>> semantics are actually needed in case 'data' is in fact initialized.
>> If I'm right, this would suggest that my recommended semantic for the
>> uninitialized lhs case (treat it as initialization) won't conflict
>> with your case here.
> What I would really like to see is this parallel:
> int a = 4;
> int& r = a;
> r = 3; // a is now 3
> int a = 4;
> optional<int&> o(a);
> o = 3; // a is now 3
> Treating uninitialized lhs as initialization of the reference would
> rule out the assignment of constants and literals, right?
Right, good point.
And BTW, using '*' the constant and literals _can_ be assigned, though of
course the behaviour is undefined if 'o' is uninitialized.