Subject: Re: [boost] Adding polymorphic_value to boost
From: Jonathan Coe (jonathanbcoe_at_[hidden])
Date: 2017-11-20 21:36:37


On 20 Nov 2017, at 21:12, Richard Hodges via Boost <boost_at_[hidden]> wrote:

>> None of these make copies. polymorphic_value is
>> not called XXX_ptr precisely because its semantics
>> are different from a pointer.
>
> shared_ptr, unique_ptr and reference_wrapper are all "different" from a
> pointer, but they all share 4 common traits:
>
> 1. The all manage/observe lifetime of another _single_ object in some
> defined but distinct way.
>
> 2. They all allow access to that object through operator*
>
> 3. They don't propagate const.
>
> 4. they don't have any pointery arithmetic behaviour
>
> Looking at the design history of polymorphic_value it seems that it
> originally came from a desire to complete the circle by providing another
> XXX_ptr which supported copying.
>
> This aim is _eminently useful_ as is evidenced by the numerous
> implementations of things like it on github (and in my own code).
>
> I also have an interest is such an object as standard because I always seem
> to end up needing one.
>
> I do not have a use case for a const-propagating one. Never have. I can
> specify const in the angle-brackets. I've done that probably once.
>
>> This situation doesn't make sense for polymorphic_value.
>
> To you perhaps. However I have 3 projects on the go right now which could
> use polymorphic_value immediately as a retro-fit for home-made solutions
> *if it did not propagate const*.
>
> The concept of propagating const I can deal with trivially. To incorporate
> it into this class mixes concerns to the detriment of its usefulness (to
> me).
>
> So If it came to a vote and my voice had any weight, I would say:
>
> * with implicit const-propagation - NO
>
> * remove the const propagation - absolute YES
>
> additionally, ideally rename it back to cloned_ptr, (or indirect if you
> must). Because what it is absolutely not is a value.
>
> It is logically the same as the other 4 non-pointers listed above, it's
> just that it have different owned-object lifetime behaviour.
>
>
> I completely understand the value-centric argument. I am a strong proponent
> of it.
>
> My argument is that this is (or ought to be) a tool for *building* value
> types. It is not in of itself a value type, and neither can it ever be. It
> does not exhibit any "value" behaviour (equality and the like).
>
> R
>
> On 20 November 2017 at 21:35, Steven Watanabe via Boost <
> boost_at_[hidden]> wrote:
>
>> AMDG
>>
>>> On 11/20/2017 01:11 PM, Richard Hodges via Boost wrote:
>>> I watched Sean Parent's talk covering what has now become
>> polymorphic_value.
>>>
>>> One thing that I am concerned about is Sean's insistence on propagating
>>> const implicitly.
>>>
>>> This would be at odds with the behaviour shared_ptr, unique_ptr, and
>>> reference_wrapper.
>>>
>>
>> None of these make copies. polymorphic_value is
>> not called XXX_ptr precisely because its semantics
>> are different from a pointer.
>>
>>> Sometimes I want a const pointer to a mutable thing, and sometimes I
>> want a
>>> mutable pointer to a const thing (and sometimes I want to be able to
>>> observe a thing without affecting its lifetime).
>>>
>>
>> This situation doesn't make sense for polymorphic_value.
>>
>>> So my 2-pence would be that propagate_const should not be implicit in
>> this
>>> class.
>>>
>>> My rationale is that an obvious use case for me would be manufacturing
>>> specialisations on pointer_type allowing a consistent interface leading
>> to
>>> an inner implementation while simply changing ownership behaviour.
>>>
>>> In that sense I am strongly of the view that the return type of
>>> polymorphic_value<Foo>::operator*() const should be Foo& and not const
>> Foo&.
>>>
>>> If I want a polymorphic cloning pointer to const Foo I can declare it
>> with
>>> polymorphic_value<const Foo>.
>>>
>>> I have never had reason to quibble with Sean's thinking before now, but
>> on
>>> this he is dead wrong.
>>>
>>> If I want const propagation, it's simple enough to wrap any pointer in
>>> propagate_const<>
>>>
>>> This feels to me like idealists overriding pragmatists.
>>>
>>> Or have I missed something obvious?
>>>
>>
>> In Christ,
>> Steven Watanabe
>>
>>
>> _______________________________________________
>> Unsubscribe & other changes: http://listarchives.boost.org/
>> mailman/listinfo.cgi/boost
>>
>
> _______________________________________________
> Unsubscribe & other changes: http://listarchives.boost.org/mailman/listinfo.cgi/boost

It’s interesting how quickly people become polarised on this. One thing to note is that polymorphic_value<const T> is not the same as a const-propagating polymorphic_value<T>; I hope that puts us all on the same page.

polymorphic_value is designed so that compiler-generated special member functions for objects with polymorphic components (sub-objects) are generated correctly. As such it needs to propagate const. There’s no sense in part of an object being mutable in a context where the object itself is immutable.

polymorphic_value solves a very real problem and allows deletion of a large amount of error-prone boiler-plate code.

Some people don’t want const-propagation because they favour a composable deep-copy + deep-const combination type. Some people have a use case for a deep-copying non const-propagating pointer-like hybrid type. Without the second category, the first is just an implementation detail. I’d really like to see real examples (not thought-experiments) that are solved by a type like cloned_ptr. I have never encountered one but my experience is not so broad and I’m well aware that absence of evidence is not evidence of absence.