Date: Fri, 21 Aug 2020 14:56:29 +0200
[Was: std::make_shared and type deduction]
As for the discussion below, the reason that I did not find the runtime polymorphic (virtual) value type val<T> useful is that I use references similar to hard links: In a pure (const) function, when one value changes in a nested container, the container must be reallocated. But this leads to complicated programming.
It might be good to replace it with a val<t> type, but for that to be convenient, the functions
virtual A* new_p() const& { return new A(*this); }
virtual A* new_p() && { return new A(std::move(*this)); }
should be added implicitly by the language to every class having virtual functions.
Then in addition one might add a clone function for deep cloning, so say that when using the ref<T> or ptr<T> types, what they point to would be copied if T has a clone function. For other types, clone defaults to copy if available, but handing over a pointer if not. (And shared_ptr<T> is essentially ptr<T> using reference counting.)
When using threads, the Boehm GC puts locks around every allocation, so if used heavily, the real time can go up when using that. Therefore a type val<T> might be better.
> On 10 Jul 2020, at 18:44, Hans Åberg via Std-Discussion <std-discussion_at_[hidden]> wrote:
>
>> On 10 Jul 2020, at 18:27, Ville Voutilainen <ville.voutilainen_at_[hidden]> wrote:
>>
>> On Fri, 10 Jul 2020 at 19:26, Hans Åberg via Std-Discussion
>> <std-discussion_at_[hidden]> wrote:
>>>
>>>
>>>> On 10 Jul 2020, at 15:31, Kyle Knoepfel via Std-Discussion <std-discussion_at_[hidden]> wrote:
>>>>
>>>>> I wasn't. I was pointing out that you're creating a new object. So maybe what
>>>>> you want is clone_unique() and clone_shared() with perfect forwarding.
>>>>
>>>> Yes, well done--clone_unique() and clone_shared() are good names. Question is would such facilities have enough interest to justify a proposal? I'm kind of doubtful....
>>>
>>> One can have polymorphic copy and move operators, by adding to every class A:
>>> virtual A* new_p() const& { return new A(*this); }
>>> virtual A* new_p() && { return new A(std::move(*this)); }
>>>
>>> Perhaps the latter would do your job.
>>
>> There are things like
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0201r5.html
>> that don't require that.
>
> I have identified three types of (virtual) polymorphy, which I use with the Boehm GC: ptr<T>, a pointer that can be a nullptr; ref<T>, a reference which is same as a pointer, but always memory allocated; val<T>, a value which invokes the above polymorphic copy and move operators.
>
> Of these three, I have found that ref<T> is most useful. With ptr<T>, one has to check that the pointer is not null, which is tedious. I have found no use for val<T>, one reason is that classes have other functions that one mostly use, so any actual need for cloning is rare. Then there is also a difference between shallow and deep cloning: Classes typically have other polymorphic pointers that one might want to be followed and cloned as well, which is the deep cloning. If one just applies the operators above, then that is the shallow cloning.
As for the discussion below, the reason that I did not find the runtime polymorphic (virtual) value type val<T> useful is that I use references similar to hard links: In a pure (const) function, when one value changes in a nested container, the container must be reallocated. But this leads to complicated programming.
It might be good to replace it with a val<t> type, but for that to be convenient, the functions
virtual A* new_p() const& { return new A(*this); }
virtual A* new_p() && { return new A(std::move(*this)); }
should be added implicitly by the language to every class having virtual functions.
Then in addition one might add a clone function for deep cloning, so say that when using the ref<T> or ptr<T> types, what they point to would be copied if T has a clone function. For other types, clone defaults to copy if available, but handing over a pointer if not. (And shared_ptr<T> is essentially ptr<T> using reference counting.)
When using threads, the Boehm GC puts locks around every allocation, so if used heavily, the real time can go up when using that. Therefore a type val<T> might be better.
> On 10 Jul 2020, at 18:44, Hans Åberg via Std-Discussion <std-discussion_at_[hidden]> wrote:
>
>> On 10 Jul 2020, at 18:27, Ville Voutilainen <ville.voutilainen_at_[hidden]> wrote:
>>
>> On Fri, 10 Jul 2020 at 19:26, Hans Åberg via Std-Discussion
>> <std-discussion_at_[hidden]> wrote:
>>>
>>>
>>>> On 10 Jul 2020, at 15:31, Kyle Knoepfel via Std-Discussion <std-discussion_at_[hidden]> wrote:
>>>>
>>>>> I wasn't. I was pointing out that you're creating a new object. So maybe what
>>>>> you want is clone_unique() and clone_shared() with perfect forwarding.
>>>>
>>>> Yes, well done--clone_unique() and clone_shared() are good names. Question is would such facilities have enough interest to justify a proposal? I'm kind of doubtful....
>>>
>>> One can have polymorphic copy and move operators, by adding to every class A:
>>> virtual A* new_p() const& { return new A(*this); }
>>> virtual A* new_p() && { return new A(std::move(*this)); }
>>>
>>> Perhaps the latter would do your job.
>>
>> There are things like
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0201r5.html
>> that don't require that.
>
> I have identified three types of (virtual) polymorphy, which I use with the Boehm GC: ptr<T>, a pointer that can be a nullptr; ref<T>, a reference which is same as a pointer, but always memory allocated; val<T>, a value which invokes the above polymorphic copy and move operators.
>
> Of these three, I have found that ref<T> is most useful. With ptr<T>, one has to check that the pointer is not null, which is tedious. I have found no use for val<T>, one reason is that classes have other functions that one mostly use, so any actual need for cloning is rare. Then there is also a difference between shallow and deep cloning: Classes typically have other polymorphic pointers that one might want to be followed and cloned as well, which is the deep cloning. If one just applies the operators above, then that is the shallow cloning.
Received on 2020-08-21 07:59:58