Topic: optional_ptr - A smart pointer which optionally owns


Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Thu, 24 Sep 2015 09:35:28 -0700 (PDT)
Raw View
------=_Part_774_167227842.1443112528108
Content-Type: multipart/alternative;
 boundary="----=_Part_775_1428606708.1443112528109"

------=_Part_775_1428606708.1443112528109
Content-Type: text/plain; charset=UTF-8

For all resources, we have owners who manage the lifetime of the resource
and viewers who view the resource. To be correct, all of the viewers have
to stop using the pointer before the last owner goes out of scope and
destroys the resource.

For both unique_ptr and shared_ptr, the set of owners and viewers has to be
decided explicitly ahead of time. This can very limiting because I've run
into cases where I have types which 99% of the time are viewers (because
the resource is often shared) but in some rare contexts need to be an owner
because the object is being used standalone with no external entity to
manage the ownership.

The heavy handed solution to use shared_ptr everywhere. Now everyone is an
owner. Using shared_ptr adds runtime overhead to manage the reference
count. The biggest problem with shared_ptr is that once you use it in one
place, you have to use it everywhere. Everything now must be dynamically
allocated individually. You can't allocate 20 objects in an array and view
one of them. You can't create objects on the stack or as a data member.
Forcing individual dynamic allocation is a performance killer. We use C++
because we need to be fast and a big part of being fast beings avoiding
allocations or failing that, batching them into fewer allocations of large
contiguous cache friendly chunks.

The solution I'm toying with now is something called optional_ptr. Maybe
its not such a great name because it could be confused with std::optional
but lets leave bikeshedding aside for now.

Essentially, optional_ptr is a move only type that works like
a variant<T*,unique_ptr<T>>. You can construct it with a raw pointer for
non-owning semantics or construct it with a unique_ptr to get owning
semantics.

The naive implementation of optional_ptr is to use T* and a bool, but for
any type with alignof(T) > 1, you can actually store the ownership bit
in lowest bit of the pointer itself since that bit will always be 0 due to
alignment. The result is that OptionalPtr has minimal runtime overhead over
unique_ptr/T* and for most types zero space overhead as well.

Using optional_ptr means an entity has the flexibility to be either an
owner or a viewer. Move only ensures unique ownership just like unique_ptr.

Here is a sketch of what it might look like:

template <typename T>
class optional_ptr {
public:
  optional_ptr() = default;
  optional_ptr(T* p) : _p(p), _own(false) {}
  optional_ptr(unique_ptr<T> p) : _p(p.release()), _own(true) {}
  ~optional_ptr() { if(_own) delete p; }

  optional_ptr(const optional_ptr<T>&) = delete;
  optional_ptr<T>& operator=(const optional_ptr<T>&) = delete;

  optional_ptr(optional_ptr<T>&&) noexcept;
  optional_ptr<T>& operator=(optional_ptr<T>&&) noexcept;

  bool owns() const { return _own; }
  T* get() const { return _p; }
  T* release() noexcept { auto* p = _p; _own = false; _p = nullptr; return p
; }
  void reset(T* p);
  void reset(unique_ptr<T> p);

  //etc...
private:
  T* _p = nullptr;
  bool _own = false;
};

How have you dealt with the problem of having a viewer which sometimes
needs to be an owner? Do you see this as a valid problem that needs
addressing or an anti-pattern?





--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_775_1428606708.1443112528109
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>For all resources, we have=C2=A0owners who manage the=
 lifetime of the resource and viewers who view the resource. To be correct,=
 all of the viewers have to stop using the pointer before the last owner go=
es out of scope and destroys the resource.</div><div>=C2=A0</div><div>For b=
oth unique_ptr and shared_ptr, the set of owners and viewers has to be deci=
ded explicitly ahead of time. This can very limiting because I&#39;ve run i=
nto cases where I have types which 99% of the time are viewers (because the=
 resource is often shared)=C2=A0but in some rare contexts need to be an own=
er because the object is being used standalone with no external entity to m=
anage the ownership.</div><div>=C2=A0</div><div>The heavy handed solution t=
o use shared_ptr everywhere. Now everyone is an owner. Using shared_ptr add=
s runtime overhead to manage the reference count. The biggest problem with =
shared_ptr is that once you use it in one place, you have to use it everywh=
ere. Everything now must be dynamically allocated individually. You can&#39=
;t allocate 20 objects in an array and view one of them. You can&#39;t crea=
te objects on the stack or as a data member. Forcing individual dynamic all=
ocation is a performance killer. We use C++ because we need to be fast and =
a big part of being fast beings avoiding allocations or failing that, batch=
ing them into fewer allocations of large contiguous cache friendly chunks.<=
/div><div>=C2=A0</div><div>The solution I&#39;m toying with now=C2=A0is som=
ething called optional_ptr. Maybe its not such a great name because it coul=
d be confused with std::optional but lets leave bikeshedding aside for now.=
</div><div>=C2=A0</div><div>Essentially, optional_ptr is a move only type t=
hat works like a=C2=A0variant&lt;T*,unique_ptr&lt;T&gt;&gt;. You can constr=
uct it with a raw pointer for non-owning semantics or construct it with a u=
nique_ptr to get owning semantics. </div><div>=C2=A0</div><div>The naive im=
plementation of optional_ptr is to use T* and a bool, but for any type with=
 alignof(T) &gt; 1, you can actually store the ownership bit in=C2=A0lowest=
 bit of the pointer itself since that bit will always be 0 due to alignment=
.. The result is that OptionalPtr has minimal runtime overhead over unique_p=
tr/T* and for most types zero space overhead as well.</div><div>=C2=A0</div=
><div>Using optional_ptr means an entity=C2=A0has the flexibility to be=C2=
=A0either an owner or a viewer. Move only ensures unique ownership just lik=
e unique_ptr.</div><div>=C2=A0</div><div>Here is=C2=A0a sketch of what it m=
ight look like:</div><div><code class=3D"prettyprint"></code>=C2=A0</div><d=
iv><code class=3D"prettyprint"><div style=3D"border: 1px solid rgb(187, 187=
, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);" class=
=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint">=
<span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">templat=
e</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> =
</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify=
">&lt;</span><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-pret=
tify">typename</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-b=
y-prettify"> T</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styl=
ed-by-prettify">&gt;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"st=
yled-by-prettify"><br></span><span style=3D"color: rgb(0, 0, 136);" class=
=3D"styled-by-prettify">class</span><span style=3D"color: rgb(0, 0, 0);" cl=
ass=3D"styled-by-prettify"> optional_ptr </span><span style=3D"color: rgb(1=
02, 102, 0);" class=3D"styled-by-prettify">{</span><span style=3D"color: rg=
b(0, 0, 0);" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
rgb(0, 0, 136);" class=3D"styled-by-prettify">public</span><span style=3D"c=
olor: rgb(102, 102, 0);" class=3D"styled-by-prettify">:</span><span style=
=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br>=C2=A0 optional_=
ptr</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prett=
ify">()</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pr=
ettify">=3D</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-=
prettify">default</span><span style=3D"color: rgb(102, 102, 0);" class=3D"s=
tyled-by-prettify">;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"st=
yled-by-prettify"><br>=C2=A0 optional_ptr</span><span style=3D"color: rgb(1=
02, 102, 0);" class=3D"styled-by-prettify">(</span><span style=3D"color: rg=
b(0, 0, 0);" class=3D"styled-by-prettify">T</span><span style=3D"color: rgb=
(102, 102, 0);" class=3D"styled-by-prettify">*</span><span style=3D"color: =
rgb(0, 0, 0);" class=3D"styled-by-prettify"> p</span><span style=3D"color: =
rgb(102, 102, 0);" class=3D"styled-by-prettify">)</span><span style=3D"colo=
r: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"color=
: rgb(102, 102, 0);" class=3D"styled-by-prettify">:</span><span style=3D"co=
lor: rgb(0, 0, 0);" class=3D"styled-by-prettify"> _p</span><span style=3D"c=
olor: rgb(102, 102, 0);" class=3D"styled-by-prettify">(</span><span style=
=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">p</span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">),</span><span s=
tyle=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> _own</span><spa=
n style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">(</span><=
span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">false</s=
pan><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">)=
</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify"=
>{}</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"=
><br>=C2=A0 optional_ptr</span><span style=3D"color: rgb(102, 102, 0);" cla=
ss=3D"styled-by-prettify">(</span><span style=3D"color: rgb(0, 0, 0);" clas=
s=3D"styled-by-prettify">unique_ptr</span><span style=3D"color: rgb(102, 10=
2, 0);" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: rgb(0=
, 0, 0);" class=3D"styled-by-prettify">T</span><span style=3D"color: rgb(10=
2, 102, 0);" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: =
rgb(0, 0, 0);" class=3D"styled-by-prettify"> p</span><span style=3D"color: =
rgb(102, 102, 0);" class=3D"styled-by-prettify">)</span><span style=3D"colo=
r: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"color=
: rgb(102, 102, 0);" class=3D"styled-by-prettify">:</span><span style=3D"co=
lor: rgb(0, 0, 0);" class=3D"styled-by-prettify"> _p</span><span style=3D"c=
olor: rgb(102, 102, 0);" class=3D"styled-by-prettify">(</span><span style=
=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">p</span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">.</span><span st=
yle=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">release</span><sp=
an style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">()),</sp=
an><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> _own<=
/span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify"=
>(</span><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify=
">true</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pr=
ettify">)</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-=
prettify">{}</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-=
prettify"><br>=C2=A0 </span><span style=3D"color: rgb(102, 102, 0);" class=
=3D"styled-by-prettify">~</span><span style=3D"color: rgb(0, 0, 0);" class=
=3D"styled-by-prettify">optional_ptr</span><span style=3D"color: rgb(102, 1=
02, 0);" class=3D"styled-by-prettify">()</span><span style=3D"color: rgb(0,=
 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(102=
, 102, 0);" class=3D"styled-by-prettify">{</span><span style=3D"color: rgb(=
0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0=
, 0, 136);" class=3D"styled-by-prettify">if</span><span style=3D"color: rgb=
(102, 102, 0);" class=3D"styled-by-prettify">(</span><span style=3D"color: =
rgb(0, 0, 0);" class=3D"styled-by-prettify">_own</span><span style=3D"color=
: rgb(102, 102, 0);" class=3D"styled-by-prettify">)</span><span style=3D"co=
lor: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: rgb(0, 0, 136);" class=3D"styled-by-prettify">delete</span><span style=
=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> p</span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">;</span><span st=
yle=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">}</span><span =
style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br><br>=C2=A0 =
optional_ptr</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled=
-by-prettify">(</span><span style=3D"color: rgb(0, 0, 136);" class=3D"style=
d-by-prettify">const</span><span style=3D"color: rgb(0, 0, 0);" class=3D"st=
yled-by-prettify"> optional_ptr</span><span style=3D"color: rgb(102, 102, 0=
);" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: rgb(0, 0,=
 0);" class=3D"styled-by-prettify">T</span><span style=3D"color: rgb(102, 1=
02, 0);" class=3D"styled-by-prettify">&gt;&amp;)</span><span style=3D"color=
: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"color:=
 rgb(102, 102, 0);" class=3D"styled-by-prettify">=3D</span><span style=3D"c=
olor: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: rgb(0, 0, 136);" class=3D"styled-by-prettify">delete</span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">;</span><span st=
yle=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br>=C2=A0 option=
al_ptr</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pr=
ettify">&lt;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-=
prettify">T</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-=
by-prettify">&gt;&amp;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"=
styled-by-prettify"> </span><span style=3D"color: rgb(0, 0, 136);" class=3D=
"styled-by-prettify">operator</span><span style=3D"color: rgb(102, 102, 0);=
" class=3D"styled-by-prettify">=3D(</span><span style=3D"color: rgb(0, 0, 1=
36);" class=3D"styled-by-prettify">const</span><span style=3D"color: rgb(0,=
 0, 0);" class=3D"styled-by-prettify"> optional_ptr</span><span style=3D"co=
lor: rgb(102, 102, 0);" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">T</span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">&gt;&amp;)</span=
><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">=3D</=
span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">del=
ete</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prett=
ify">;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pretti=
fy"><br><br>=C2=A0 optional_ptr</span><span style=3D"color: rgb(102, 102, 0=
);" class=3D"styled-by-prettify">(</span><span style=3D"color: rgb(0, 0, 0)=
;" class=3D"styled-by-prettify">optional_ptr</span><span style=3D"color: rg=
b(102, 102, 0);" class=3D"styled-by-prettify">&lt;</span><span style=3D"col=
or: rgb(0, 0, 0);" class=3D"styled-by-prettify">T</span><span style=3D"colo=
r: rgb(102, 102, 0);" class=3D"styled-by-prettify">&gt;&amp;&amp;)</span><s=
pan style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> noexcept</=
span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">=
;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><=
br>=C2=A0 optional_ptr</span><span style=3D"color: rgb(102, 102, 0);" class=
=3D"styled-by-prettify">&lt;</span><span style=3D"color: rgb(0, 0, 0);" cla=
ss=3D"styled-by-prettify">T</span><span style=3D"color: rgb(102, 102, 0);" =
class=3D"styled-by-prettify">&gt;&amp;</span><span style=3D"color: rgb(0, 0=
, 0);" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 0,=
 136);" class=3D"styled-by-prettify">operator</span><span style=3D"color: r=
gb(102, 102, 0);" class=3D"styled-by-prettify">=3D(</span><span style=3D"co=
lor: rgb(0, 0, 0);" class=3D"styled-by-prettify">optional_ptr</span><span s=
tyle=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">&lt;</span><=
span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">T</span><s=
pan style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">&gt;&am=
p;&amp;)</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pret=
tify"> noexcept</span><span style=3D"color: rgb(102, 102, 0);" class=3D"sty=
led-by-prettify">;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styl=
ed-by-prettify"><br>=C2=A0 <br>=C2=A0 </span><span style=3D"color: rgb(0, 0=
, 136);" class=3D"styled-by-prettify">bool</span><span style=3D"color: rgb(=
0, 0, 0);" class=3D"styled-by-prettify"> owns</span><span style=3D"color: r=
gb(102, 102, 0);" class=3D"styled-by-prettify">()</span><span style=3D"colo=
r: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"color=
: rgb(0, 0, 136);" class=3D"styled-by-prettify">const</span><span style=3D"=
color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: rgb(102, 102, 0);" class=3D"styled-by-prettify">{</span><span style=
=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=
=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">return</span><span=
 style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> _own</span><s=
pan style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">;</span=
><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">}</sp=
an><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br>=
=C2=A0 T</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-=
prettify">*</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-=
prettify">get</span><span style=3D"color: rgb(102, 102, 0);" class=3D"style=
d-by-prettify">()</span><span style=3D"color: rgb(0, 0, 0);" class=3D"style=
d-by-prettify"> </span><span style=3D"color: rgb(0, 0, 136);" class=3D"styl=
ed-by-prettify">const</span><span style=3D"color: rgb(0, 0, 0);" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: rgb(102, 102, 0);" class=
=3D"styled-by-prettify">{</span><span style=3D"color: rgb(0, 0, 0);" class=
=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 0, 136);" clas=
s=3D"styled-by-prettify">return</span><span style=3D"color: rgb(0, 0, 0);" =
class=3D"styled-by-prettify"> _p</span><span style=3D"color: rgb(102, 102, =
0);" class=3D"styled-by-prettify">;</span><span style=3D"color: rgb(0, 0, 0=
);" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(102, 102=
, 0);" class=3D"styled-by-prettify">}</span><span style=3D"color: rgb(0, 0,=
 0);" class=3D"styled-by-prettify"><br>=C2=A0 T</span><span style=3D"color:=
 rgb(102, 102, 0);" class=3D"styled-by-prettify">*</span><span style=3D"col=
or: rgb(0, 0, 0);" class=3D"styled-by-prettify"> release</span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">()</span><span s=
tyle=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> noexcept </span=
><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">{</s=
pan><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">auto=
</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify=
">*</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"=
> p </span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pret=
tify">=3D</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pre=
ttify"> _p</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-b=
y-prettify">;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by=
-prettify"> _own </span><span style=3D"color: rgb(102, 102, 0);" class=3D"s=
tyled-by-prettify">=3D</span><span style=3D"color: rgb(0, 0, 0);" class=3D"=
styled-by-prettify"> </span><span style=3D"color: rgb(0, 0, 136);" class=3D=
"styled-by-prettify">false</span><span style=3D"color: rgb(102, 102, 0);" c=
lass=3D"styled-by-prettify">;</span><span style=3D"color: rgb(0, 0, 0);" cl=
ass=3D"styled-by-prettify"> _p </span><span style=3D"color: rgb(102, 102, 0=
);" class=3D"styled-by-prettify">=3D</span><span style=3D"color: rgb(0, 0, =
0);" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 0, 1=
36);" class=3D"styled-by-prettify">nullptr</span><span style=3D"color: rgb(=
102, 102, 0);" class=3D"styled-by-prettify">;</span><span style=3D"color: r=
gb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"color: rg=
b(0, 0, 136);" class=3D"styled-by-prettify">return</span><span style=3D"col=
or: rgb(0, 0, 0);" class=3D"styled-by-prettify"> p</span><span style=3D"col=
or: rgb(102, 102, 0);" class=3D"styled-by-prettify">;</span><span style=3D"=
color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: rgb(102, 102, 0);" class=3D"styled-by-prettify">}</span><span style=
=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br>=C2=A0 </span><s=
pan style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">void</spa=
n><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> reset<=
/span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify"=
>(</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">=
T</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettif=
y">*</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify=
"> p</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pret=
tify">);</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pret=
tify"><br>=C2=A0 </span><span style=3D"color: rgb(0, 0, 136);" class=3D"sty=
led-by-prettify">void</span><span style=3D"color: rgb(0, 0, 0);" class=3D"s=
tyled-by-prettify"> reset</span><span style=3D"color: rgb(102, 102, 0);" cl=
ass=3D"styled-by-prettify">(</span><span style=3D"color: rgb(0, 0, 0);" cla=
ss=3D"styled-by-prettify">unique_ptr</span><span style=3D"color: rgb(102, 1=
02, 0);" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: rgb(=
0, 0, 0);" class=3D"styled-by-prettify">T</span><span style=3D"color: rgb(1=
02, 102, 0);" class=3D"styled-by-prettify">&gt;</span><span style=3D"color:=
 rgb(0, 0, 0);" class=3D"styled-by-prettify"> p</span><span style=3D"color:=
 rgb(102, 102, 0);" class=3D"styled-by-prettify">);</span><span style=3D"co=
lor: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br><br>=C2=A0 </span><spa=
n style=3D"color: rgb(136, 0, 0);" class=3D"styled-by-prettify">//etc...</s=
pan><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br><=
/span><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">p=
rivate</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pr=
ettify">:</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pre=
ttify"><br>=C2=A0 T</span><span style=3D"color: rgb(102, 102, 0);" class=3D=
"styled-by-prettify">*</span><span style=3D"color: rgb(0, 0, 0);" class=3D"=
styled-by-prettify"> _p </span><span style=3D"color: rgb(102, 102, 0);" cla=
ss=3D"styled-by-prettify">=3D</span><span style=3D"color: rgb(0, 0, 0);" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 0, 136);" c=
lass=3D"styled-by-prettify">nullptr</span><span style=3D"color: rgb(102, 10=
2, 0);" class=3D"styled-by-prettify">;</span><span style=3D"color: rgb(0, 0=
, 0);" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color:=
 rgb(0, 0, 136);" class=3D"styled-by-prettify">bool</span><span style=3D"co=
lor: rgb(0, 0, 0);" class=3D"styled-by-prettify"> _own </span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">=3D</span><span =
style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">false</span><s=
pan style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">;</span=
><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> <br></s=
pan><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">}=
;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><=
br></span></div></code></div><br>How have you dealt with the problem of hav=
ing a viewer which sometimes needs to be an owner? Do you see this as a val=
id problem that needs addressing or an anti-pattern?</code></div><code clas=
s=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: rgb(0=
, 0, 136);" class=3D"styled-by-prettify"></span>=C2=A0</div></code><br><div=
>=C2=A0</div><div>=C2=A0</div></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_775_1428606708.1443112528109--
------=_Part_774_167227842.1443112528108--

.