Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2005-10-15 13:21:35


Joel de Guzman <joel_at_[hidden]> writes:

> 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.

I *really* don't have an opinion about what the right choice should
be. That said, terms like gobbledegook seem needlessly judgemental,
and as such I think they only cloud the issues.

> There *is* an alternative design which is a lot simpler and I've
> been saying that again and again: do as the structs do.

I guess you're assuming optional<T&> maps onto a struct with a T&
member? That model is not 100% obvious to me. The only way to
initialize a plain struct with a reference member is using an
initializer list, and the assignment operator for such a struct can't
be used.

  struct X { int& y; };
  int z = 3;
  X x = { z };
  X y( x = x );

--
  "ComeauTest.c", line 1: error: implicitly generated assignment operator cannot copy:
              reference member "X::y"
    struct X { int& y; };
           ^
            detected during implicit generation of "X &X::operator=(const X &)"
                      at line 5
So "the structs" in this case are never that simple, and they don't
provide a guide for what to do with optional<T&>, since the assigment
behavior for reference members is always explicitly decided by some
class designer.
> It is easier to visualize and understand and ultimately to explain.
> A more complex design and behavior will surely lead to more gotchas.
Seems to me there's plenty of room for confusion in the behavior you
want.
  optional<X&> o;
  X x;
  o = x;           // Reference bound; no copy ctor called.
  o = x;           // X's copy ctor called
> Keep it as simple as possible. variant<T&, nil> does
> the right thing. I don't understand why optional can't. 
Surely it _can_ do the same thing as variant<T&, nil>.  It's just not
as obvious to everyone that it's the "one true behavior" for
optional<T&>.  It's not like we're discussing the choice between Emacs
and every other editor on the planet ;-)
> Perhaps it's because of the dual pointer interface. But, like Mat
> Marcus, I also don't buy the pointer model: "Pointers can be null or
> dereference-able, Optionals can be null or dereferenceable,
> therefore Optionals are models of Pointers". 
I don't know if anyone actually made that argument or not, but
optionals don't have to be models of Pointers in order to justify the
operator*, operator->, and operator safe_bool.  The Pointer and
Optional concepts could be refinements of some concept that includes
nullability and dereferenceability.
I'd really like to see a careful and non-judgemental comparison of the
two possible design choices, describing the advantages and
disadvantages of each one.  Until we see something like that, I doubt
we will be able to come to a useful consensus.
-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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