Boost logo

Boost :

From: Glen Fernandes (glen.fernandes_at_[hidden])
Date: 2020-01-29 13:06:04


On Wed, Jan 29, 2020 at 7:22 AM Gavin Lambert via Boost
<boost_at_[hidden]> wrote:
>
> At 19:02 29/01/2020, Glen Fernandes wrote:
> >You shouldn't expect that. For any unique_ptr<T, D> you can only
> >expect that .get() gives you a D::pointer. For default_delete<T>
>
> >this might be T*. But it always depends on the Deleter.
>
> That seems like a significantly more annoying interface than
> std::shared_ptr uses.

Yes. This is because shared_ptr erases D and A. And therefore even
erases A::pointer which might be a fancy-pointer.

> Having that be an implementation detail of the deleter changing
> the effective "type" of the first template argument (which is what
> people think of as the type of the pointer, even if the standard
> disagrees) seems quite annoying.
>

It does not change the effective type of anything. This is what
unique_ptr<T, D> was designed for. People are just used to
unique_ptr<T> or where D uses raw-pointers.

> >The correct way to get a raw pointer from any
> >potentially-fancy-pointer x is: to_address(x)
> >
> >This can be boost::to_address (C++03 or higher), or
> >std::to_address (C++20 or higher)
>
> Hmm. This is news to me; I don't think I've read about it
> anywhere in conjunction with unique_ptr. Perhaps since it doesn't
> actually exist yet (most compilers are still mostly C++17).

unique_ptr supporting fancy pointers exists since C++11.

boost::to_address works since C++03. And pre-std::to_address even in
C++ standard library implementations we used __to_address and
__to_raw_pointer for this task. i.e. Obtaining a raw pointer from a
fancy pointer. We never assume things like Allocator pointers are raw
pointers.

(std::to_address was just standardizing existing practice that was
already in use, e.g. in GCC libstdc++ for many years)

> https://en.cppreference.com/w/cpp/memory/unique_ptr
> appears entirely mute on the topic. (There's a passing reference
> to fancy pointers but even that doesn't talk about it.)

That's all it needs to say. to_address isn't related to unique_ptr.
  It's for any pointer-or-fancy-pointer pointer-like types.

For unique_ptr<T, D>, where D::pointer might be fancy, and .get() can
return this potentially-fancy pointer, the only guaranteed way to get
a raw pointer from it is: to_address(p.get());

Before C++20 std::to_address we just used our own utilities that did
the same thing. But boost::to_address works even in C++03 and above
and most Boost libraries that deal with Allocators where the pointers
can be fancy already use it.

Glen


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