$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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