From: Joe Gottman (jgottman_at_[hidden])
Date: 2005-10-14 21:28:08


"Joel de Guzman" <joel_at_[hidden]> wrote in message
news:diphko$tba$1_at_sea.gmane.org...
> David Abrahams wrote:
>> Joel de Guzman <joel_at_[hidden]> writes:
>>
>>
>>>>Rebinding semantics are there _precisely_ and _only_ to solve a problem
>>>>posed by nullability.
>>>
>>>Sorry, I don't buy that.
>>
>>
>> Why not?
>
> I think this is again an artifact of the confusion between the
> dual interfaces that optional provides. optional has an identity
> crisis of being a pointer (as the author's original model) and
> a variant<T, nil> (which I suggested later on). The rebinding
> behavior that Fernando rationalized was long and winding and
> confusing. I don't recall anymore his exact rationale. All I
> know is that when you have to explain your design using so much
> wordings, then something is wrong, and I don't buy the gobbledegook.

  Here is an interesting thought experiment. What should std::swap do with
optional<X &>? In general, swap(x, y) usually has the same effect as the
following code, except for perhaps a stronger exception guarantee and faster
performance:
    Foo temp(x); // Step 1. Assume x and y are of type Foo
    x = y; // Step 2
    y = temp; // Step 3

That being the case, what would the following code do?
    int a = 1;
    int b = 2;
    optional<int &> x(a);
    optional<int &> y(b);
    swap(x, y);

   Assume that swap is not specialized for optional, and consider two cases.
   Case 1: rebind.
       Step 1 of swap above binds temp to a, step 2 rebinds x to b and step
3 rebinds y to a. Thus the end result is that x and y are each rebound to
what the other one was pointing to before.

   Case 2: no rebind.
      In this case, Step 1 above binds temp to a as before. But step 2
results in *x = *y, so a is set equal to b and both a and b now equal 2.
Then step 3 results in *y = *temp, so b is set equal to a, but since a and b
are already equal due to step 1, there results in no change. Thus the end
result is that the original value in a is lost.

Of course we would specialize swap for optional<T> to call swap(*x, *y) if
both x and y are initialized, but I think the fact that this is not
equivalent to the unspecialized version is an argument in favor of the
rebind semantics.

Joe Gottman