Boost logo

Boost :

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


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