Date: Tue, 23 Aug 2022 14:21:36 +0200
On 23.08.2022 13:28, Frederick Virchanza Gotham via Std-Proposals wrote:
> At first I was going to suggest that classes such as "unique_ptr",
> "shared_ptr" and "weak_ptr" should inherit from a common interface
> which has a virtual destructor, something like:
>
> class ISmartPtr {
> public:
> virtual ~ISmartPtr(void);
> };
>
> class unique_ptr : public ISmartPtr { . . . };
> class shared_ptr : public ISmartPtr { . . . };
> class weak_ptr : public ISmartPtr { . . . };
>
> So this would mean that we could have a container that automatically
> destroys any kind of smart pointer as follows:
>
> vector<ISmartPtr> my_vector;
>
> But then I thought it would be useful if *every* class inherited from
> a class with a virtual destructor. As if doing this:
>
> struct MyClass { int a; }
>
> would be the same as:
>
> struct BaseClassWithVirtualDestructor { virtual
> ~BaseClassWithVirtualDestructor(){} };
>
> struct MyClass : public BaseClassWithVirtualDestructor {
> int a;
> };
>
> But of course that would mean that all simple POD's would have the
> overhead of a pointer to a v-table (and also the address of the first
> member would not be equal to the address of the object -- on most
> architectures).
>
> But then I thought of another idea, how about we have a new type
> called "dvoid", and a new cast called 'virtual_destructor_cast':
>
> Some_POD_Class a;
> Some_Complicated_Class_With_Virtual_Destructor b;
>
> dvoid *p = virtual_destructor_cast<dvoid*>(&a); // This returns a nullptr
> dvoid *p = virtual_destructor_cast<dvoid*>(&b); // This returns a
> valid pointer
>
> And then you can use this pointer as follows:
>
> p->~dvoid();
>
> or perhaps an alternative syntax would be:
>
> std::destroy(p);
>
> So then you could have a container of pointers to anything that can be
> destroyed:
>
> std::vector<dvoid*> objects;
>
> In order to implement the 'dvoid*' type on a system where a pointer is
> 8 bytes, the 'dvoid' type could be 16 bytes, as internally it would be
> two pointers:
> (1) The pointer to the object
> (2) The pointer to the destructor of the object (possibly obtained
> from the v-table)
Hi Frederick.
I wonder if maybe std::vector<std::any> would do the trick for you?
I believe you should be able to push there whatever you want and it
would be destroyed properly upon destruction of the container.
Alternatively use
std::variant<std::unique_ptr<T>, std::shared_ptr<T>, std::weak_ptr<T>>
if you want more constrained type.
std::best_regards();
> At first I was going to suggest that classes such as "unique_ptr",
> "shared_ptr" and "weak_ptr" should inherit from a common interface
> which has a virtual destructor, something like:
>
> class ISmartPtr {
> public:
> virtual ~ISmartPtr(void);
> };
>
> class unique_ptr : public ISmartPtr { . . . };
> class shared_ptr : public ISmartPtr { . . . };
> class weak_ptr : public ISmartPtr { . . . };
>
> So this would mean that we could have a container that automatically
> destroys any kind of smart pointer as follows:
>
> vector<ISmartPtr> my_vector;
>
> But then I thought it would be useful if *every* class inherited from
> a class with a virtual destructor. As if doing this:
>
> struct MyClass { int a; }
>
> would be the same as:
>
> struct BaseClassWithVirtualDestructor { virtual
> ~BaseClassWithVirtualDestructor(){} };
>
> struct MyClass : public BaseClassWithVirtualDestructor {
> int a;
> };
>
> But of course that would mean that all simple POD's would have the
> overhead of a pointer to a v-table (and also the address of the first
> member would not be equal to the address of the object -- on most
> architectures).
>
> But then I thought of another idea, how about we have a new type
> called "dvoid", and a new cast called 'virtual_destructor_cast':
>
> Some_POD_Class a;
> Some_Complicated_Class_With_Virtual_Destructor b;
>
> dvoid *p = virtual_destructor_cast<dvoid*>(&a); // This returns a nullptr
> dvoid *p = virtual_destructor_cast<dvoid*>(&b); // This returns a
> valid pointer
>
> And then you can use this pointer as follows:
>
> p->~dvoid();
>
> or perhaps an alternative syntax would be:
>
> std::destroy(p);
>
> So then you could have a container of pointers to anything that can be
> destroyed:
>
> std::vector<dvoid*> objects;
>
> In order to implement the 'dvoid*' type on a system where a pointer is
> 8 bytes, the 'dvoid' type could be 16 bytes, as internally it would be
> two pointers:
> (1) The pointer to the object
> (2) The pointer to the destructor of the object (possibly obtained
> from the v-table)
Hi Frederick.
I wonder if maybe std::vector<std::any> would do the trick for you?
I believe you should be able to push there whatever you want and it
would be destroyed properly upon destruction of the container.
Alternatively use
std::variant<std::unique_ptr<T>, std::shared_ptr<T>, std::weak_ptr<T>>
if you want more constrained type.
std::best_regards();
-- Michał Gawron mcv.mulabs.org
Received on 2022-08-23 12:21:40