Date: Wed, 30 Apr 2025 17:47:09 +0200
> On 30 Apr 2025, at 15:55, Ville Voutilainen <ville.voutilainen_at_[hidden]> wrote:
>
> On Wed, 30 Apr 2025 at 16:33, Hans Åberg via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
>>> 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.
>>
>> An addition might be that one can write
>> class A {
>> virtual A* new_p(void* p) const& = default;
>> virtual A* new_p(void* p) && = default;
>> };
>> with the implication that every derived class D of A, as well as A, gets
>> class D : A
>> virtual D* new_p(void* p) const& { return new D(*this); }
>> virtual D* new_p(void* p) && { return new D(std::move(*this)); }
>> };
>
> So, use https://eel.is/c++draft/polymorphic
The primary issue is to get proper copy and move of derived classes. On top of that, one can think of different interfaces.
There I keep the allocation and the val<A> type together. So I have
// Placeholder struct and value
struct make_t {};
constexpr make_t make{};
val<A> av(make, …); // Applies new A(…)
rather than
A* ap = new A(…);
val<A> av(ap;
I cannot ditch the “make” argument, as there will be conflicts with the class val<A> constructors.
I cannot see how your proposal relates to that.
>
> On Wed, 30 Apr 2025 at 16:33, Hans Åberg via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
>>> 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.
>>
>> An addition might be that one can write
>> class A {
>> virtual A* new_p(void* p) const& = default;
>> virtual A* new_p(void* p) && = default;
>> };
>> with the implication that every derived class D of A, as well as A, gets
>> class D : A
>> virtual D* new_p(void* p) const& { return new D(*this); }
>> virtual D* new_p(void* p) && { return new D(std::move(*this)); }
>> };
>
> So, use https://eel.is/c++draft/polymorphic
The primary issue is to get proper copy and move of derived classes. On top of that, one can think of different interfaces.
There I keep the allocation and the val<A> type together. So I have
// Placeholder struct and value
struct make_t {};
constexpr make_t make{};
val<A> av(make, …); // Applies new A(…)
rather than
A* ap = new A(…);
val<A> av(ap;
I cannot ditch the “make” argument, as there will be conflicts with the class val<A> constructors.
I cannot see how your proposal relates to that.
Received on 2025-04-30 15:47:26