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