Re: [boost] Yet Another Container: DynamicArray
At 19:02 29/01/2020, Glen Fernandes wrote:
You shouldn't expect that. For any unique_ptr
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. shared_ptr can hold fancy pointers too, but it happens explicitly via using fancy<T> rather than plain T, so the explicit indirection on usage is obvious too. 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. Maybe we should have a type-erased unique ownership pointer as well. I know the reason why we didn't was to avoid heap allocation or wasted storage for the common case, but there ought to be some happy middle ground.
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). But eg. https://en.cppreference.com/w/cpp/memory/unique_ptrhttps://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.)
On Wed, Jan 29, 2020 at 7:22 AM Gavin Lambert via Boost
At 19:02 29/01/2020, Glen Fernandes wrote:
You shouldn't expect that. For any unique_ptr
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
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
On Wed, Jan 29, 2020 at 4:22 AM Gavin Lambert via Boost < boost@lists.boost.org> wrote:
At 19:02 29/01/2020, Glen Fernandes wrote:
You shouldn't expect that. For any unique_ptr
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.
shared_ptr can hold fancy pointers too, but it happens explicitly via using fancy<T> rather than plain T, so the explicit indirection on usage is obvious too.
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.
Maybe we should have a type-erased unique ownership pointer as well. I know the reason why we didn't was to avoid heap allocation or wasted storage for the common case, but there ought to be some happy middle ground.
What you're describing is shared_ptr with the copy ctor deleted and a move ctor that swaps with the source or some such. You'll pay for the storage and the initialization of the refcounters but that's probably negligible. We just need someone from WG21 to take a stab at implementing it to compare its performance to shared_ptr, on single-threaded Windows. :)
participants (3)
-
Emil Dotchevski
-
Gavin Lambert
-
Glen Fernandes