Date: Wed, 30 Apr 2025 17:20:35 +0100
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.
What you're describing is commonly called a clone operation. Calling
it "new" just confuses things.
<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.
What you're describing is commonly called a clone operation. Calling
it "new" just confuses things.
Received on 2025-04-30 16:20:50