On Wed, Jan 29, 2020 at 12:55 AM Gavin Lambert via Boost <boost@lists.boost.org> wrote:
On 29/01/2020 18:39, Glen Fernandes wrote:
Basically, a unique_ptr result from an allocate_unique<T[]>(a, n) _has_ to store the n somewhere in the unique_ptr because it needs to know how many objects to destroy and what size storage to deallocate.
I also provide access for you to get that n. (I just forgot to put it in the documentation).
Does it also implicitly decay to a T*?
Why would it decay to a T*? It's a pointer-like type, for which operator* and operator-> give you the right thing. It doesn't decay to T* nor does it decay to A::pointer (which may not even be T*, i.e. it could be a fancy pointer).
(I did have a look at> https://github.com/boostorg/smart_ptr/blob/master/include/boost/smart_ptr/al... but I don't see any `operator T*`, which is what I'd expect.)
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.
If not, that seems like it'd make it hard to pass to something expecting a raw pointer (eg. as method argument, or to construct a std::span).
For any given generic unique_ptr<T, D> p; the way to get a T* raw pointer is not just p.get(). D::pointer can always be a fancy pointer (i.e. a pointer-like type that is not a raw pointer). 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) Glen