Boost logo

Boost :

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!


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