C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Polymorphic operator new and polymorphic values

From: Robin Savonen Söderholm <robinsavonensoderholm_at_[hidden]>
Date: Wed, 30 Apr 2025 18:59:59 +0200
Please take a look at Inheritance Is The Base Class Of Evil, it shows
exactly how you can get the copy and move constructors inte the vtable
without manual work.. Link here:
https://youtu.be/bIhUE5uUFOA?si=1tztfcExmYFubitd


// Robin

On Wed, Apr 30, 2025, 18:55 Hans Åberg via Std-Proposals <
std-proposals_at_[hidden]> wrote:

>
> > On 30 Apr 2025, at 18:20, Jonathan Wakely <cxx_at_[hidden]> wrote:
> >
> > On Wed, 30 Apr 2025 at 17:05, Hans Åberg via Std-Proposals
> > <std-proposals_at_[hidden]> wrote:
> >>
> >>
> >>> On 30 Apr 2025, at 15:53, Jason McKesson via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
> >>>
> >>> On Wed, Apr 30, 2025 at 9:33 AM Hans Åberg via Std-Proposals
> >>> <std-proposals_at_[hidden]> wrote:
> >>>>
> >>>>
> >>>>> On 30 Apr 2025, at 14:55, Jonathan Wakely <cxx_at_[hidden]> wrote:
> >>>>>
> >>>>> On Wed, 30 Apr 2025 at 10:56, Hans Åberg <haberg_1_at_[hidden]>
> wrote:
> >>>>>>
> >>>>>>
> >>>>>>> On 30 Apr 2025, at 11:22, Jonathan Wakely <cxx_at_[hidden]> wrote:
> >>>>>>>
> >>>>>>> On Wed, 30 Apr 2025 at 10:06, Hans Åberg via Std-Proposals
> >>>>>>> <std-proposals_at_[hidden]> wrote:
> >>>>>>>>
> >>>>>>>> I am using polymorphic (runtime, virtual) values val<A>; all
> classes A in the virtual hierarchy must have a polymorphic operator new.
> The polymorphic operator new is already present in C++, but one has to
> write it in by hand in each class; otherwise, the polymorphic copy and move
> operators will not work correctly.
> >>>>>>>>
> >>>>>>>> I primarily want a way to automate this, with an addition to the
> language, say by adding “default” in the base class and then also the
> derived classes get it, or alternatively, the template system. It would
> also be nice to be able to use the keyword “new” instead of something else
> like “new_p“.
> >>>>>>>>
> >>>>>>>> In my experience, the polymorphic values val<T> are better for
> objects that semantically are values than GC references, as the latter
> easily lead to programming errors. They also fit well with the C++
> programming model, especially in view of move operators and C++17 copy
> elision.
> >>>>>>>>
> >>>>>>>> So polymorphic values could be added to C++, in their own right.
> >>>>>>>>
> >>>>>>>> The code for the class val<A> is in the file polymorphy.hh, and
> the operator new_p is defined in the file MLI.hh at lines 347–348:
> >>>>>>>>
> https://git.savannah.gnu.org/cgit/metalogic-inference.git/tree/src
> >>>>>>>
> >>>>>>> Why should it be in the standard? It doesn't seem like something
> that
> >>>>>>> many people will use.
> >>>>>>
> >>>>>> The polymorphic operator new should be supported in derived classes
> somehow, as it is easy to forget when adding a new class, and then copy and
> move will be wrong.
> >>>>>
> >>>>> I don't even know what polymorphic operator new means, so this
> doesn't
> >>>>> seem like a very common scenario. Who would benefit from it being in
> >>>>> the standard?
> >>>>
> >>>> The polymorphic operator new is also called a clone operator or a
> virtual copy operator, given such names rather than “new”. As I also use it
> for move, I call them polymorphic operator new. As “new” is a reserved
> word, it cannot be used without additions to the language.
> >>>>
> >>>>>> As for the val<A> type, I think the GC references are generally
> used just as a hack for polymorphic values:
> >>>>>>
> >>>>>> One can use reference counting, like in std::shared_ptr, or say the
> Boehm GC. But then one will have to remember when to copy an object, and
> there one gets errors in the implementation.
> >>>>>
> >>>>> I'm still not sure what you're actually proposing for the standard.
> >>>>
> >>>> Suppose:
> >>>> class A {
> >>>> virtual A* new_p(void* p) const& { return new A(*this); }
> >>>> };
> >>>>
> >>>> class B : A {
> >>>> virtual B* new_p(void* p) const& { return new B(*this); }
> >>>> };
> >>>>
> >>>> class C : A {
> >>>> // No new_p
> >>>> };
> >>>>
> >>>> Then:
> >>>> A* bp = new B, cp = new C;
> >>>> bp->new_p(); // Gets a copy of *bp
> >>>> cp->new_p(); // Gets a copy of A(*cp)
> >>>> In the last copy, the object gets truncated to A, not the wanted full
> C object.
> >>>>
> >>>> So one must add by hand new_p to every new class created that is
> derived from A.
> >>>
> >>> So it's really a polymorphic copy, not a "new".
> >>
> >> I use that name because polymorphic copy and move are really variations
> of “new”.
> >
> > But you said "operator new" and that's something different, that's a
> > function that allocates raw memory and returns void*.
> >
> > Maybe you mean "the new operator" which is frustratingly similar in
> > name to "operator new" but is the thing that allocates *and
> > constructs* a new object.
>
> Sorry for the confusion. :-)
>
> > What you're describing is commonly called a clone operation. Calling
> > it "new" just confuses things.
>
> What is meant is the new operator, as in “new A{…}”.
>
> So it should be the “polymorphic new operator” then, or “virtual new
> operator” is perhaps better.
>
> It is better to reuse names already present, rather than create new ones,
> which I recall is a C++ policy.
>
> The motivation for suggesting using “new” here is that the uses are quite
> similar:
> A* ap = new A(…);
> A* bp = ap->new A();
>
> Anyway, adding a new class alone cannot solve the issue of proper virtual
> copy and move, as the functions for doing that must be present, and
> currently they are not part of the vtables unless added by hand.
>
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2025-04-30 17:00:15