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-01 05:42:34


Quick note: I just subscribed to the list, and perhaps because I had
"digest mode" switched on until just now, this was the first reply I
received. Are there any other replies I haven't seen?

On Wed, Feb 1, 2017 at 6:24 PM, Oswin Krause <
Oswin.Krause_at_[hidden]> wrote:

> Hi,
>
> Can observer_ptr refer to no object? If not, why not just use T &? If
>> so, why not just use optional<T>?
>>
>
> As far as i understood it, it is still assignable, unlike T&.
>

`observer_ptr<T>` can be null; `observer<T>` cannot. `T&` is not the same
in a number of ways:

   - `T&` cannot be "rebound" after construction.
   - `T&` makes containing classes non-copy assignable by default
   - `T&` cannot be stored in arrays
   - `T&` cannot be stored in containers (though I saw maybe this is a
   feature being added to the C++ standard?)
   - `T&` has value assignment and comparison semantics (they operate on
   the referenced value); the observer types have reference (pointer-like)
   assignment and comparison semantics. They behave very differently with
   algorithms and containers (

`reference_wrapper` has reference assignment semantics, which makes it work
properly in containers, but it still has value comparison semantics.

Essentially, `T&` (and `reference_wrapper<T>`) is not a pointer type, and
has totally different semantics. `observer_ptr` and `observer` have pointer
semantics and are useful where pointers would be useful.

For me, the biggest problem of the proposal is that observer_ptr<T> is
> implicitely constructed from T&. In my code I often use:
>
> Foo a;
> Bar b(&a);//&a signals that b only references to a, but does not copy it.
>
> Now, when I write
>
> Bar b(a); //so is a now copied?
>
> While the interface is clearer in documentation, the usage is less clear!
>

I personally have used this pattern in code before without confusion:

bar(foo const& f) : m_f(&f) {}

Indeed, the documented interface is clearer if you use `observer<foo
const>`, but the calling code looks the same.

I did anticipate that this might be a problem for some people (though I am
personally comfortable with it). If this is a widespread concern, the
implicit conversion from `T&` could be removed `make_observer` would become
the recommended way to create an `observer`:

Bar b(make_observer(a));


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