$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] Is there any interest in non-owning pointer-like types?
From: Joseph Thomson (joseph.thomson_at_[hidden])
Date: 2017-02-04 07:25:30
On Sat, Feb 4, 2017 at 2:59 PM, David Stone <david_at_[hidden]> wrote:
> Using optional does not imply any overhead. You simply provide a
> specialization for optional<observer<T>>. You make optional<observer<T>> a
> friend of observer<T>, and create a private constructor that acts as the
> back door to allow your type to store a nullptr inside it to represent the
> empty state. Then the only way to get in this state is through optional, so
> users of the type never see that such a state is possible.
>
This is quite true. I did consider this, but for some reason dismissed it.
But I guess this optimization would be allowable under the as-if rule
<http://en.cppreference.com/w/cpp/language/as_if>? Of course, this is
contingent on `observer<T>` becoming part of the C++ standard.
> The behavior of operator< is a little trickier. That being said, I do not
> believe that this type should have operator<. This type is not usable as an
> iterator, which is the only situation where operator< makes sense for
> pointer types. Instead, I would just specialize std::less (which I see you
> delegate to in your operator<) to allow use in std::map. Then the question
> of the performance of optional's operator< goes away, because it is not
> defined.
>
Sounds reasonable. I only defined the operators to allow storage in
ordered associative containers, but you are right that this only requires a
specialization of `less`.
I have a minor gripe with `optional<observer<T>>` because you end up having
to double dereference to access the underlying object:
optional<observer<int>> ooi = some_int;
**ooi = 42;
That said, I am also slightly annoyed at the fact that, after removing
implicit conversion from `T&`, there is no neat way to convert an
`observer_ptr<T>` to an `observer<T>`. With `optional<observer<T>>`, this
is not a problem (because of the double dereferencing):
optional<observer<int>> ooi = some_int;
observer<int> oi = *ooi;
int i = **ooi;
However, I have come to appreciate that syntactic brevity is not always a
sign of correct design, and syntax is rarely a compelling justification for
a design decision. In this case I believe the double dereference may be
warranted.
Thanks for your input. It is very useful!