220 27940 <CAJnLdObcZYq+NrDQHD4QN2V_qZV+qBzPcMeh3725g8eF6_JD6g@mail.gmail.com> article
Path: news.gmane.org!.POSTED!not-for-mail
From: "'Edward Catmur' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Re: We need const_shared_ptr<T>
Date: Thu, 25 Aug 2016 16:27:41 +0100
Lines: 317
Approved: news@gmane.org
Message-ID: <CAJnLdObcZYq+NrDQHD4QN2V_qZV+qBzPcMeh3725g8eF6_JD6g@mail.gmail.com>
References: <c3616c21-a33a-44b7-9912-b8ce927b57e9@isocpp.org>
 <444132ec-e8f3-400d-81b2-330a016702ee@isocpp.org> <45b8bdc7-5463-428a-aaef-d25ba0d2aa76@isocpp.org>
 <b627ed17-df02-4577-8a43-cc1af308673b@isocpp.org> <CAJnLdOZtv5pNcS5iUH0kAiCyfqHPWq+UF4ZKziPY5j4Doa_B5w@mail.gmail.com>
 <5aacde88-8fb7-476c-a87e-df4d6ab001ae@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary=94eb2c08a748ea6743053ae7090f
X-Trace: blaine.gmane.org 1472138867 8801 195.159.176.226 (25 Aug 2016 15:27:47 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Thu, 25 Aug 2016 15:27:47 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBDZLZTXF7UJBB3U47S6QKGQE5GYPY2A@isocpp.org Thu Aug 25 17:27:42 2016
Return-path: <std-proposals+bncBDZLZTXF7UJBB3U47S6QKGQE5GYPY2A@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-yw0-f198.google.com ([209.85.161.198])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBDZLZTXF7UJBB3U47S6QKGQE5GYPY2A@isocpp.org>)
	id 1bcwZC-0001th-IT
	for gclcip-std-proposals@m.gmane.org; Thu, 25 Aug 2016 17:27:42 +0200
Original-Received: by mail-yw0-f198.google.com with SMTP id j12sf90338578ywb.3
        for <gclcip-std-proposals@m.gmane.org>; Thu, 25 Aug 2016 08:27:43 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=mime-version:in-reply-to:references:from:date:message-id:subject:to
         :x-original-sender:x-original-authentication-results:reply-to
         :precedence:mailing-list:list-id:x-spam-checked-in-group:list-post
         :list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=s5LU7RWL6J6hskqboxbg4gNivdpHf8bKdy/srPaexqw=;
        b=oIcRnjBbmnwQKEVYDU70zT9vAwSzpcv7pDb0zyRyvHbnFRyr/sG3tYf5rtF8Mdi6BR
         YbzerAfUUq1fxphmL8rmg15H1qbTayP9h4xE8vqIvuiTd0zWt7W9cOypILZJNYHxoFl1
         /L4DHFViKaJJIBGHOF4dImKKijm1Ys+5+zuQLmcWSzvRBRkVtk6zE7LbNrMoW/5Aov4v
         AutrRBduIGloFJomMchGsquRzpR2Guy+PzulrmYu3VvlEmcw6HEbrjj1aY5daRlEgW38
         UN/eXWSWPeUeH4Wha1oHu1vAgUeyWkOW0pcOKXAn+fv+uR29xMZkPeSLz3TEU1K8HOUS
         9AKQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:mime-version:in-reply-to:references:from:date
         :message-id:subject:to:x-original-sender
         :x-original-authentication-results:reply-to:precedence:mailing-list
         :list-id:x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=s5LU7RWL6J6hskqboxbg4gNivdpHf8bKdy/srPaexqw=;
        b=dMHAv6EFT+ViDo/IbOEY3qamrfUgeVHcE4/JixB+0Dw/5G8ulF7EAME888mL/XbS1j
         OIxCrlYAxZOM1Aat+Ey/s0LjxzE2oURJ3/cHxtLzumGl0qjYVUuoZAnRMutk4j4QWj1R
         k+EuHXvT2jBEAdf/tEQyzVS+U80tsMI7DOmUxzLlPk6rdOWPjNOWp95TDhFNY0Gp0HaR
         E2vP6wpT7pdyQKvoGWA1Ce9DpElzqq/JPdQMxDkj89rrAMTLbe8yhQ7YuaS/zdSd40vz
         n6XNXuyYoKxpn470xsvHdBXLJiQuelDUlvTmsXARNDioUsgCI/sS/gncYODzyW/UwniG
         SU9w==
X-Gm-Message-State: AE9vXwP787rAyZoWjTRZ7KgBsCapNLF+bmRHJFaCScSkxGcSvGp7w6TxRupuDGMxHCejNQ==
X-Received: by 10.157.26.107 with SMTP id u40mr6686779otu.44.1472138863208;
        Thu, 25 Aug 2016 08:27:43 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.157.24.71 with SMTP id t7ls1225103ott.5.gmail; Thu, 25 Aug
 2016 08:27:42 -0700 (PDT)
X-Received: by 10.200.57.108 with SMTP id t41mr10956347qtb.33.1472138862167;
        Thu, 25 Aug 2016 08:27:42 -0700 (PDT)
Original-Received: from mail-qk0-x230.google.com (mail-qk0-x230.google.com. [2607:f8b0:400d:c09::230])
        by mx.google.com with ESMTPS id 132si10728552qkf.152.2016.08.25.08.27.42
        for <std-proposals@isocpp.org>
        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Thu, 25 Aug 2016 08:27:42 -0700 (PDT)
Received-SPF: pass (google.com: domain of ecatmur@googlemail.com designates 2607:f8b0:400d:c09::230 as permitted sender) client-ip=2607:f8b0:400d:c09::230;
Original-Received: by mail-qk0-x230.google.com with SMTP id t7so49061103qkh.1
        for <std-proposals@isocpp.org>; Thu, 25 Aug 2016 08:27:42 -0700 (PDT)
X-Received: by 10.55.146.67 with SMTP id u64mr10409471qkd.6.1472138861763;
 Thu, 25 Aug 2016 08:27:41 -0700 (PDT)
Original-Received: by 10.237.32.135 with HTTP; Thu, 25 Aug 2016 08:27:41 -0700 (PDT)
In-Reply-To: <5aacde88-8fb7-476c-a87e-df4d6ab001ae@isocpp.org>
X-Original-Sender: ecatmur@googlemail.com
X-Original-Authentication-Results: mx.google.com;       dkim=pass
 header.i=@googlemail.com;       spf=pass (google.com: domain of
 ecatmur@googlemail.com designates 2607:f8b0:400d:c09::230 as permitted
 sender) smtp.mailfrom=ecatmur@googlemail.com;       dmarc=pass (p=QUARANTINE
 dis=NONE) header.from=googlemail.com
X-Original-From: Edward Catmur <ecatmur@googlemail.com>
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:27940
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/27940>

--94eb2c08a748ea6743053ae7090f
Content-Type: text/plain; charset=UTF-8

On Thu, Aug 25, 2016 at 3:10 PM, Nicol Bolas <jmckesson@gmail.com> wrote:

> On Thursday, August 25, 2016 at 3:29:28 AM UTC-4, Edward Catmur wrote:
>>
>> On 25 Aug 2016 1:54 a.m., "Nicol Bolas" <jmck...@gmail.com> wrote:
>> >
>> > On Wednesday, August 24, 2016 at 7:57:33 PM UTC-4, Edward Catmur wrote:
>> >>
>> >> On Wednesday, 24 August 2016 15:45:12 UTC+1, Nicol Bolas  wrote:
>> >> > On Wednesday, August 24, 2016 at 3:39:33 AM UTC-4, Alexey Mamontov
>> wrote:
>> >> >
>> >> > There is an interesting concept of pointers pair: const_shared with
>> mutable_unique.
>> >> >
>> >> > Const shared is move-constructible from mutable_unique: this enqures
>> that the value we have a const shared pointer to can not be references for
>> edit from any other location (the problem that shared_ptr<const T> can't
>> solve).
>> >> >
>> >> > Why does it not solve this problem? Outside of `const_pointer_cast`
>> or similar gymnastics, if you have a `shared_ptr<const T>`, you cannot
>> convert it into a `shared_ptr<T>`. Oh sure, you can always `get` the
>> pointer and `const_cast` it. But your `const_shared_ptr` has no way to
>> prevent that either.
>> >>
>> >> But there can be an already existing shared_ptr<T> aliasing your
>> shared_ptr<T const>.
>> >
>> >
>> > Without a `const_cast` or similar? If you do `make_shared<const
>> T>(...)`, I have no idea how you would get the aliasing to `shared_ptr<T>`
>> without a `const_cast` or similar.
>> >
>> > At least, not unless it's a pointer to a different `T`.
>>
>> If you do make_shared<T>(...) then you can get a shared_ptr<T const>
>> later that has the same target as the original shared_ptr<T>.
>>
>
> I fail to see your point.
>
> My point is that `shared_ptr` gives a user all the tools that
> `const_shared_ptr` gives the user for making a non-modifiable shared
> pointer to T. Namely, `shared_ptr<const T>`. If you create it `const`
> initially, then nobody can take that away without an explicit `const_cast`
> or similar construct.
>
> This, in regards to the const-ness of `T`, `shared_ptr` is just as
> guaranteed as the proposed `const_shared_ptr`. Indeed, you could do this:
>
> template<typename T>
> using const_shared_ptr = std::shared_ptr<std::add_const_t<T>>;
>
> template<typename T, template ...Args>
> auto make_const_shared(Args &&...args) { return std::make_shared<std::add_
> const_t<T>>(std::forward<Args>(args)...); }
>
> And you get the same `const` protection as the proposed
> `const_shared_ptr`, so long as that is how you create them initially.
>

Right, but only if you control all the locations where the shared_ptr<T
[const]> is created and will be created in the future. If someone hands you
a shared_ptr<T const> it might have been created by make_shared<T const>
but it might also have been created initially as a make_shared<T>, so you
can't be sure that no-one has a mutable handle to the object you're
accessing.

> >> > Indeed, I would even go so far as to say that, if this is the idea,
>> then giving it an existing object to govern is really the wrong interface.
>> Such a type should create the objects it manages internally; this would
>> allow the implementation to be more efficient (ala `make_shared`). That is,
>> you construct the mutable unique value type, then move the value into your
>> "const" COW shared object.
>> >> >
>> >> > So what you really have is `unique_value<T>` and `shared_value<const
>> T>`, with conversions between them. This also permits you to have a mutable
>> `shared_value<T>` if a user wants it, rather than enforcing immutability at
>> the interface level.
>> >>
>> >> Would that allow enforcement of non modification by an aliasing value?
>> There's two sides to immutability; there's "I can't modify it" and there's
>> "no-one can modify it".
>> >
>> >
>> > Conceptually, it's a value type, so it wouldn't have aliasing of any
>> form. What would that even mean? Would you be aliasing a value with another
>> value? Indeed, the OP excluded aliasing from `const_shared_ptr`'s
>> interface, since it doesn't make sense.
>>
>> Sorry, I didn't mean aliasing in the sense of creating a shared_ptr to a
>> subobject, rather in the general sense of one pointer having the same
>> target as another pointer, or one reference having the same referent as
>> another reference.
>>
>> In your shared_value scheme, a modification to one shared_value<T> can be
>> observed by another shared_value with the same target. Can you prevent a
>> shared_value<T const> having the same target as a shared_value<T>?
>>
>
> The same way as I showed for `shared_ptr`: make it `const` when you create
> the first one.
>
> If you want pure COW semantics from the type I've suggested, then you make
> a `shared_value<const T>` at the point of origin. At no time do you make a
> `shared_value<T>`.
>

But then you can *never* modify it; you can only copy it to a new mutable
value. Which is great for functional purity, but could also be inefficient.

The thing is, I've always thought we should have a `value_ptr<T>` type.
> That is, a type that *certainly* allocates memory for `T`, moves via moving
> the pointer, but copies itself by copying the object by value. This would
> be useful for cases where `T` is expensive to move and/or throws on moving.
>
> A `shared_value_ptr<T>` would not be an unreasonable pairing for such a
> type. And then we could have `shared_value_ptr<const T>` serve the needs
> the OP requires for COW gymnastics, so long as there is a conversion from
> `shared_value_ptr` to `value_ptr` which is permitted to avoid a copy if the
> `shared_value_ptr` moved into it is the last one.
>

But that conversion would give you a value_ptr<T const>, so it would still
be immutable even when it should be safe to mutate.

-- 
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJnLdObcZYq%2BNrDQHD4QN2V_qZV%2BqBzPcMeh3725g8eF6_JD6g%40mail.gmail.com.

--94eb2c08a748ea6743053ae7090f
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On T=
hu, Aug 25, 2016 at 3:10 PM, Nicol Bolas <span dir=3D"ltr">&lt;<a href=3D"m=
ailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>&gt;</s=
pan> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0p=
x 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-lef=
t-style:solid;padding-left:1ex"><div dir=3D"ltr">On Thursday, August 25, 20=
16 at 3:29:28 AM UTC-4, Edward Catmur wrote:<blockquote class=3D"gmail_quot=
e" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-colo=
r:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><p dir=3D"ltr"=
></p>
<p dir=3D"ltr">On 25 Aug 2016 1:54 a.m., &quot;Nicol Bolas&quot; &lt;<a rel=
=3D"nofollow">jmck...@gmail.com</a>&gt; wrote:<br>
&gt;<br>
&gt; On Wednesday, August 24, 2016 at 7:57:33 PM UTC-4, Edward Catmur wrote=
:<br>
&gt;&gt;<br>
&gt;&gt; On Wednesday, 24 August 2016 15:45:12 UTC+1, Nicol Bolas =C2=A0wro=
te: <br>
&gt;&gt; &gt; On Wednesday, August 24, 2016 at 3:39:33 AM UTC-4, Alexey Mam=
ontov wrote: <br>
&gt;&gt; &gt; <br>
&gt;&gt; &gt; There is an interesting concept of pointers pair: const_share=
d=C2=A0with mutable_unique.=C2=A0 <br>
&gt;&gt; &gt; <br>
&gt;&gt; &gt; Const shared is move-constructible from mutable_unique: this =
enqures that the value we have a const shared=C2=A0pointer to can not be re=
ferences for edit from any other location (the problem=C2=A0that shared_ptr=
&lt;const T&gt; can&#39;t solve). <br>
&gt;&gt; &gt; <br>
&gt;&gt; &gt; Why does it not solve this problem? Outside of `const_pointer=
_cast` or similar gymnastics, if you have a `shared_ptr&lt;const T&gt;`, yo=
u cannot convert it into a `shared_ptr&lt;T&gt;`. Oh sure, you can always `=
get` the pointer and `const_cast` it. But your `const_shared_ptr` has no wa=
y to prevent that either. <br>
&gt;&gt;<br>
&gt;&gt; But there can be an already existing shared_ptr&lt;T&gt; aliasing =
your shared_ptr&lt;T const&gt;.<br>
&gt;<br>
&gt;<br>
&gt; Without a `const_cast` or similar? If you do `make_shared&lt;const T&g=
t;(...)`, I have no idea how you would get the aliasing to `shared_ptr&lt;T=
&gt;` without a `const_cast` or similar.<br>
&gt;<br>
&gt; At least, not unless it&#39;s a pointer to a different `T`.</p>
<p dir=3D"ltr">If you do make_shared&lt;T&gt;(...) then you can get a share=
d_ptr&lt;T const&gt; later that has the same target as the original shared_=
ptr&lt;T&gt;.</p></blockquote><div><br>I fail to see your point.<br><br>My =
point is that `shared_ptr` gives a user all the tools that `const_shared_pt=
r` gives the user for making a non-modifiable shared pointer to T. Namely, =
`shared_ptr&lt;const T&gt;`. If you create it `const` initially, then nobod=
y can take that away without an explicit `const_cast` or similar construct.=
<br><br>This, in regards to the const-ness of `T`, `shared_ptr` is just as =
guaranteed as the proposed `const_shared_ptr`. Indeed, you could do this:<b=
r><br><div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-word;=
background-color:rgb(250,250,250)"><code><div><span style=3D"color:rgb(0,0,=
136)">template</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span =
style=3D"color:rgb(0,0,136)">typename</span><span style=3D"color:rgb(0,0,0)=
"> T</span><span style=3D"color:rgb(102,102,0)">&gt;</span><span style=3D"c=
olor:rgb(0,0,0)"><br></span><span style=3D"color:rgb(0,0,136)">using</span>=
<span style=3D"color:rgb(0,0,0)"> const_shared_ptr </span><span style=3D"co=
lor:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> std</span><=
span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0=
)">shared_ptr</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span s=
tyle=3D"color:rgb(0,0,0)">std</span><span style=3D"color:rgb(102,102,0)">::=
</span><span style=3D"color:rgb(0,0,0)">add_<wbr>const_t</span><span style=
=3D"color:rgb(102,102,0)">&lt;</span><span style=3D"color:rgb(0,0,0)">T</sp=
an><span style=3D"color:rgb(102,102,0)">&gt;&gt;;</span><span style=3D"colo=
r:rgb(0,0,0)"><br><br></span><span style=3D"color:rgb(0,0,136)">template</s=
pan><span style=3D"color:rgb(102,102,0)">&lt;</span><span style=3D"color:rg=
b(0,0,136)">typename</span><span style=3D"color:rgb(0,0,0)"> T</span><span =
style=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"> </=
span><span style=3D"color:rgb(0,0,136)">template</span><span style=3D"color=
:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">...</span><span s=
tyle=3D"color:rgb(102,0,102)">Args</span><span style=3D"color:rgb(102,102,0=
)">&gt;</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"co=
lor:rgb(0,0,136)">auto</span><span style=3D"color:rgb(0,0,0)"> make_const_s=
hared</span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"col=
or:rgb(102,0,102)">Args</span><span style=3D"color:rgb(0,0,0)"> </span><spa=
n style=3D"color:rgb(102,102,0)">&amp;&amp;...</span><span style=3D"color:r=
gb(0,0,0)">args</span><span style=3D"color:rgb(102,102,0)">)</span><span st=
yle=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">{</sp=
an><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,13=
6)">return</span><span style=3D"color:rgb(0,0,0)"> std</span><span style=3D=
"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">make_share=
d</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span style=3D"colo=
r:rgb(0,0,0)">std</span><span style=3D"color:rgb(102,102,0)">::</span><span=
 style=3D"color:rgb(0,0,0)">add_<wbr>const_t</span><span style=3D"color:rgb=
(102,102,0)">&lt;</span><span style=3D"color:rgb(0,0,0)">T</span><span styl=
e=3D"color:rgb(102,102,0)">&gt;&gt;(</span><span style=3D"color:rgb(0,0,0)"=
>std</span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"col=
or:rgb(0,0,0)">forward</span><span style=3D"color:rgb(102,102,0)">&lt;</spa=
n><span style=3D"color:rgb(102,0,102)">Args</span><span style=3D"color:rgb(=
102,102,0)">&gt;<wbr>(</span><span style=3D"color:rgb(0,0,0)">args</span><s=
pan style=3D"color:rgb(102,102,0)">)...);</span><span style=3D"color:rgb(0,=
0,0)"> </span><span style=3D"color:rgb(102,102,0)">}</span></div></code></d=
iv><br>And you get the same `const` protection as the proposed `const_share=
d_ptr`, so long as that is how you create them initially.<br></div></div></=
blockquote><div><br></div><div>Right, but only if you control all the locat=
ions where the shared_ptr&lt;T [const]&gt; is created and will be created i=
n the future. If someone hands you a shared_ptr&lt;T const&gt; it might hav=
e been created by make_shared&lt;T const&gt; but it might also have been cr=
eated initially as a make_shared&lt;T&gt;, so you can&#39;t be sure that no=
-one has a mutable handle to the object you&#39;re accessing.</div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-wid=
th:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-l=
eft:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(2=
04,204,204);border-left-style:solid;padding-left:1ex"><p dir=3D"ltr">&gt;&g=
t; &gt; Indeed, I would even go so far as to say that, if this is the idea,=
 then giving it an existing object to govern is really the wrong interface.=
 Such a type should create the objects it manages internally; this would al=
low the implementation to be more efficient (ala `make_shared`). That is, y=
ou construct the mutable unique value type, then move the value into your &=
quot;const&quot; COW shared object. <br>
&gt;&gt; &gt; <br>
&gt;&gt; &gt; So what you really have is `unique_value&lt;T&gt;` and `share=
d_value&lt;const T&gt;`, with conversions between them. This also permits y=
ou to have a mutable `shared_value&lt;T&gt;` if a user wants it, rather tha=
n enforcing immutability at the interface level. <br>
&gt;&gt;<br>
&gt;&gt; Would that allow enforcement of non modification by an aliasing va=
lue? There&#39;s two sides to immutability; there&#39;s &quot;I can&#39;t m=
odify it&quot; and there&#39;s &quot;no-one can modify it&quot;.<br>
&gt;<br>
&gt;<br>
&gt; Conceptually, it&#39;s a value type, so it wouldn&#39;t have aliasing =
of any form. What would that even mean? Would you be aliasing a value with =
another value? Indeed, the OP excluded aliasing from `const_shared_ptr`&#39=
;s interface, since it doesn&#39;t make sense.</p>
<p dir=3D"ltr">Sorry, I didn&#39;t mean aliasing in the sense of creating a=
 shared_ptr to a subobject, rather in the general sense of one pointer havi=
ng the same target as another pointer, or one reference having the same ref=
erent as another reference. </p>
<p dir=3D"ltr">In your shared_value scheme, a modification to one shared_va=
lue&lt;T&gt; can be observed by another shared_value with the same target. =
Can you prevent a shared_value&lt;T const&gt; having the same target as a s=
hared_value&lt;T&gt;?<br></p></blockquote><div><br>The same way as I showed=
 for `shared_ptr`: make it `const` when you create the first one.<br><br>If=
 you want pure COW semantics from the type I&#39;ve suggested, then you mak=
e a `shared_value&lt;const T&gt;` at the point of origin. At no time do you=
 make a `shared_value&lt;T&gt;`.<br></div></div></blockquote><div><br></div=
><div>But then you can *never* modify it; you can only copy it to a new mut=
able value. Which is great for functional purity, but could also be ineffic=
ient.</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin=
:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204)=
;border-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><div>The thing =
is, I&#39;ve always thought we should have a `value_ptr&lt;T&gt;` type. Tha=
t is, a type that *certainly* allocates memory for `T`, moves via moving th=
e pointer, but copies itself by copying the object by value. This would be =
useful for cases where `T` is expensive to move and/or throws on moving.<br=
><br>A `shared_value_ptr&lt;T&gt;` would not be an unreasonable pairing for=
 such a type. And then we could have `shared_value_ptr&lt;const T&gt;` serv=
e the needs the OP requires for COW gymnastics, so long as there is a conve=
rsion from `shared_value_ptr` to `value_ptr` which is permitted to avoid a =
copy if the `shared_value_ptr` moved into it is the last one.</div></div></=
blockquote><div><br></div><div>But that conversion would give you a value_p=
tr&lt;T const&gt;, so it would still be immutable even when it should be sa=
fe to mutate.<br></div><div><br></div><div>=C2=A0</div></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAJnLdObcZYq%2BNrDQHD4QN2V_qZV%2BqBzP=
cMeh3725g8eF6_JD6g%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJnLdObcZYq%=
2BNrDQHD4QN2V_qZV%2BqBzPcMeh3725g8eF6_JD6g%40mail.gmail.com</a>.<br />

--94eb2c08a748ea6743053ae7090f--

.
