Topic: vector<T*> vs vector<unique_ptr<T>> problems
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Wed, 14 Jan 2015 15:55:55 -0800 (PST)
Raw View
------=_Part_6169_1652658947.1421279755282
Content-Type: multipart/alternative;
boundary="----=_Part_6170_685431931.1421279755282"
------=_Part_6170_685431931.1421279755282
Content-Type: text/plain; charset=UTF-8
We have unique_ptr<T[]> and vector<unique_ptr<T>> but there is one big use
case where both are inadequate.
struct FooSlow {
std::vector<T*> getSubset(int i) const { return { _v.begin() + i, _v.end()
}; }
std::vector<std::unique_ptr<T>> _v;
};
struct FooFast {
carray_view<T*> getSubset(int i) const { return { _v.begin() + 1, _v.end()
}; }
std::vector<T*> _v;
~FooFast() { while(!_v.empty()) { delete v.back(); v.pop_back(); } }
};
Here we have a linear array of pointers in our Foo object and want to
return a view to a subsection of the array. With vector<unique_ptr<T>>, we
are forced to create a copy because of the type system.
With vector<T*>, we can directly return a view referencing a subset but now
we have to take care of copy(), copy=, move(), move=, and the destructor.
Has there been any talk about a managed vector of pointers?
Having a std::ptr_vector<T*> or something similar which has the same
operations as vector but cleans up the underlying memory would fix this
issue.
struct FooFast {
carray_view<T*> getSubset(int i) const { return { _v.begin() + 1, _v.end()
}; }
std::ptr_vector<T*> _v;
};
Another alternative would be to have some guarantee in the standard that
reinterpret_cast<T*>(std::unique_ptr<T>()) is valid. That is that a
unique_ptr with default deleter is exactly the same as raw pointer in terms
of memory layout and we can do some ugly casting.
template <typename T>
T** unique_ptr_cast<T>(unique_ptr<T>* ptr) { return reinterpret_cast<T**>(
ptr); }
struct FooFast {
carray_view<T*> getSubset(int i) const { return { unique_ptr_cast(_v.data()
+ i), unique_ptr_cast(_v.data() + v.size()) }; }
std::vector<std::unique_ptr<T*>> _v;
};
Thoughts?
--
---
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_6170_685431931.1421279755282
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div> We have unique_ptr<T[]> and vector<uni=
que_ptr<T>> but there is one big use case where both are inadequat=
e.</div><div> </div><div> </div><div style=3D"border: 1px solid r=
gb(187, 187, 187); word-wrap: break-word; background-color: rgb(250, 250, 2=
50);" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subpr=
ettyprint"><font color=3D"#000088"><span style=3D"color: rgb(0, 0, 136);" c=
lass=3D"styled-by-prettify">struct</span></font><span style=3D"color: rgb(0=
, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(10=
2, 0, 102);" class=3D"styled-by-prettify">FooSlow</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"><br> std</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">vector</sp=
an><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">&l=
t;</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-pret=
tify"> getSubset</span><span style=3D"color: rgb(102, 102, 0);" class=3D"st=
yled-by-prettify">(</span><span style=3D"color: rgb(0, 0, 136);" class=3D"s=
tyled-by-prettify">int</span><span style=3D"color: rgb(0, 0, 0);" class=3D"=
styled-by-prettify"> i</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">const</span><span style=3D"color: rgb(0, 0, 0);" c=
lass=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">return</span><span style=3D"color: rgb(0, 0,=
0);" class=3D"styled-by-prettify"> </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"> _v</span><span style=3D"color: rgb(10=
2, 102, 0);" class=3D"styled-by-prettify">.</span><span style=3D"color: rgb=
(0, 0, 136);" class=3D"styled-by-prettify">begin</span><span style=3D"color=
: rgb(102, 102, 0);" class=3D"styled-by-prettify">()</span><span style=3D"c=
olor: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: rgb(102, 102, 0);" class=3D"styled-by-prettify">+</span><span style=3D=
"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> i</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"> _v</span><span styl=
e=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">.</span><span s=
tyle=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">end</span><spa=
n 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"> </spa=
n><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><font color=3D"#666600"><span style=3D"color: rgb(0, 0, 0);" class=
=3D"styled-by-prettify"> std</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">vector</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">std</span><span style=3D"colo=
r: rgb(102, 102, 0);" class=3D"styled-by-prettify">::</span><span style=3D"=
color: rgb(0, 0, 0);" class=3D"styled-by-prettify">unique_ptr</span><span s=
tyle=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><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"> =
_v</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pretti=
fy">;</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettif=
y"><br></span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-p=
rettify">};</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-p=
rettify"><br><br></span><span style=3D"color: rgb(0, 0, 136);" class=3D"sty=
led-by-prettify">struct</span><span style=3D"color: rgb(0, 0, 0);" class=3D=
"styled-by-prettify"> </span><span style=3D"color: rgb(102, 0, 102);" class=
=3D"styled-by-prettify">FooFast</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> carray_view</span><span style=3D"=
color: rgb(102, 102, 0);" class=3D"styled-by-prettify"><</span><span sty=
le=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">T</span><span styl=
e=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">*></span><sp=
an style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> getSubset</=
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"=
>int</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify=
"> i</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-prett=
ify"> </span><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-pret=
tify">const</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-p=
rettify"> </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"> </span><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-b=
y-prettify">return</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styl=
ed-by-prettify"> </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"> _v</span><span style=3D"color: rgb(102, 102, 0);" class=
=3D"styled-by-prettify">.</span><span style=3D"color: rgb(0, 0, 136);" clas=
s=3D"styled-by-prettify">begin</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"> </span><span style=3D"color: rgb(0, 102,=
102);" class=3D"styled-by-prettify">1</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"> _v</span><span style=3D"color: rgb(=
102, 102, 0);" class=3D"styled-by-prettify">.</span><span style=3D"color: r=
gb(0, 0, 136);" class=3D"styled-by-prettify">end</span><span style=3D"color=
: rgb(102, 102, 0);" class=3D"styled-by-prettify">()</span><span style=3D"c=
olor: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: 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 st=
yle=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br> std</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">v=
ector</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pre=
ttify"><</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-p=
rettify">T</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"style=
d-by-prettify"> _v</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"s=
tyled-by-prettify"><br><br> </span><span style=3D"color: rgb(102, 102=
, 0);" class=3D"styled-by-prettify">~</span><span style=3D"color: rgb(102, =
0, 102);" class=3D"styled-by-prettify">FooFast</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"> </span><span style=3D"colo=
r: rgb(102, 102, 0);" class=3D"styled-by-prettify">{</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">while</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">_v</span><span s=
tyle=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">.</span><spa=
n style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">empty</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(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">de=
lete</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify=
"> v</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-prett=
ify">back</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-b=
y-prettify"> v</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styl=
ed-by-prettify">.</span><span style=3D"color: rgb(0, 0, 0);" class=3D"style=
d-by-prettify">pop_back</span><span style=3D"color: rgb(102, 102, 0);" clas=
s=3D"styled-by-prettify">();</span><span style=3D"color: rgb(0, 0, 0);" cla=
ss=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);" c=
lass=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></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></span></font><span style=3D"color:=
rgb(0, 0, 0);" class=3D"styled-by-prettify"><br></span></div></code></div>=
<div><br>Here we have a linear array of pointers in our Foo object and want=
to return a view to a subsection of the array. With vector<unique_ptr&l=
t;T>>, we are forced to create a copy because of the type system.</di=
v><div> </div><div>With vector<T*>, we can directly return a vie=
w referencing a subset but now we have to take care of copy(=
), copy=3D, move(), move=3D, and the destructor.</div><div> </div><div=
>Has there been any talk about a managed vector of pointers?</div><div>Havi=
ng a std::ptr_vector<T*> or something similar which has the same oper=
ations as vector but cleans up the underlying memory would fix this issue.<=
/div><div> </div><div style=3D"border: 1px solid rgb(187, 187, 187); w=
ord-wrap: break-word; background-color: rgb(250, 250, 250);" class=3D"prett=
yprint"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span sty=
le=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">struct</span><sp=
an style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: rgb(102, 0, 102);" class=3D"styled-by-prettify">FooFast</=
span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </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"><b=
r> carray_view</span><span style=3D"color: rgb(102, 102, 0);" class=
=3D"styled-by-prettify"><</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">*></span><span style=3D"color: rgb(0, 0, 0)=
;" class=3D"styled-by-prettify"> getSubset</span><span style=3D"color: rgb(=
102, 102, 0);" class=3D"styled-by-prettify">(</span><span style=3D"color: r=
gb(0, 0, 136);" class=3D"styled-by-prettify">int</span><span style=3D"color=
: rgb(0, 0, 0);" class=3D"styled-by-prettify"> i</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">const</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 st=
yle=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">return</span><sp=
an style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><spa=
n 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"> _v</span>=
<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">.</sp=
an><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">begi=
n</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-prettif=
y"> </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-prett=
ify"> </span><span style=3D"color: rgb(0, 102, 102);" class=3D"styled-by-pr=
ettify">1</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"> _v</span><span style=3D"color: rgb(102, 102, 0);" class=3D"style=
d-by-prettify">.</span><span style=3D"color: rgb(0, 0, 136);" class=3D"styl=
ed-by-prettify">end</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"> </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"><br> std</span><span style=3D"color: rgb(10=
2, 102, 0);" class=3D"styled-by-prettify">::</span><span style=3D"color: rg=
b(0, 0, 0);" class=3D"styled-by-prettify">ptr_vector</span><span style=3D"c=
olor: rgb(102, 102, 0);" class=3D"styled-by-prettify"><</span><span styl=
e=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">*></span><spa=
n style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> _v</span><sp=
an 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></spa=
n><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">};<=
/span></div></code></div><p> </p><div>Another alternative would be to =
have some guarantee in the standard that reinterpret_cast<T*>(std::un=
ique_ptr<T>()) is valid. That is that a unique_ptr with default delet=
er is exactly the same as raw pointer in terms of memory layout and we can =
do some ugly casting.</div><div> </div><div><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">template</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, 136);" c=
lass=3D"styled-by-prettify">typename</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">></span><span style=3D"color: rgb(=
0, 0, 0);" class=3D"styled-by-prettify"><br>T</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"> unique_ptr_cast</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-prettify">>(=
</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">un=
ique_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-b=
y-prettify">T</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"st=
yled-by-prettify"> 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"> </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"> </span><span style=3D"color: rgb(0, 0, 136);" cl=
ass=3D"styled-by-prettify">return</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">reinterpret_cast</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-prettify">**>(</span><span =
style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">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"> </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><br>=
</span><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">=
struct</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: rgb(102, 0, 102);" class=3D"styled-by-pre=
ttify">FooFast</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-b=
y-prettify"> </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"styled=
-by-prettify"><br> carray_view</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">T</span><span style=3D"color: rgb(10=
2, 102, 0);" class=3D"styled-by-prettify">*></span><span style=3D"color:=
rgb(0, 0, 0);" class=3D"styled-by-prettify"> getSubset</span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">int</span><span=
style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> i</span><span=
style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">)</span><s=
pan style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">const</spa=
n><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">{</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">retu=
rn</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-prettif=
y">{</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify=
"> unique_ptr_cast</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"s=
tyled-by-prettify">_v</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">data</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"> i</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"> unique_ptr_cast</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">_v</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">data</span><span =
style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">()</span><s=
pan style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><sp=
an 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"> v</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">size</=
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-pretti=
fy">};</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pre=
ttify">}</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pret=
tify"><br> std</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">vector</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">std</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">unique_ptr</span><span style=3D"color: =
rgb(102, 102, 0);" class=3D"styled-by-prettify"><</span><span style=3D"c=
olor: rgb(0, 0, 0);" class=3D"styled-by-prettify">T</span><span style=3D"co=
lor: rgb(102, 102, 0);" class=3D"styled-by-prettify">*>></span><span =
style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> _v</span><span=
style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">;</span><s=
pan style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br></span>=
<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">};</s=
pan></div></code></div><span style=3D"color: rgb(102, 102, 0);" class=3D"st=
yled-by-prettify"><br>Thoughts?</span></div><div><br></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" 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_6170_685431931.1421279755282--
------=_Part_6169_1652658947.1421279755282--
.
Author: Nicola Gigante <nicola.gigante@gmail.com>
Date: Thu, 15 Jan 2015 16:46:28 +0100
Raw View
--Apple-Mail=_DDF4DB73-BB2D-4820-B048-D59826A07651
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> Il giorno 15/gen/2015, alle ore 00:55, Matthew Fioravante <fmatthew5876@g=
mail.com> ha scritto:
>=20
> We have unique_ptr<T[]> and vector<unique_ptr<T>> but there is one big u=
se case where both are inadequate.
> =20
> =20
> struct FooSlow {
> std::vector<T*> getSubset(int i) const { return { _v.begin() + i, _v.en=
d() }; }
> std::vector<std::unique_ptr<T>> _v;
> };
>=20
> struct FooFast {
> carray_view<T*> getSubset(int i) const { return { _v.begin() + 1, _v.en=
d() }; }
> std::vector<T*> _v;
>=20
> ~FooFast() { while(!_v.empty()) { delete v.back(); v.pop_back(); } }
> };
>=20
>=20
> Here we have a linear array of pointers in our Foo object and want to ret=
urn a view to a subsection of the array. With vector<unique_ptr<T>>, we are=
forced to create a copy because of the type system.
> =20
> With vector<T*>, we can directly return a view referencing a subset but n=
ow we have to take care of copy(), copy=3D, move(), move=3D, and the destru=
ctor.
> =20
> Has there been any talk about a managed vector of pointers?
> Having a std::ptr_vector<T*> or something similar which has the same oper=
ations as vector but cleans up the underlying memory would fix this issue.
> =20
> struct FooFast {
> carray_view<T*> getSubset(int i) const { return { _v.begin() + 1, _v.en=
d() }; }
> std::ptr_vector<T*> _v;
> };
> =20
> Another alternative would be to have some guarantee in the standard that =
reinterpret_cast<T*>(std::unique_ptr<T>()) is valid. That is that a unique_=
ptr with default deleter is exactly the same as raw pointer in terms of mem=
ory layout and we can do some ugly casting.
> =20
> template <typename T>
> T** unique_ptr_cast<T>(unique_ptr<T>* ptr) { return reinterpret_cast<T**>=
(ptr); }
>=20
> struct FooFast {
> carray_view<T*> getSubset(int i) const { return { unique_ptr_cast(_v.dat=
a() + i), unique_ptr_cast(_v.data() + v.size()) }; }
> std::vector<std::unique_ptr<T*>> _v;
> };
>=20
> Thoughts?
>=20
Hi.
I had a similar design problem recently but I solved it with ranges.
If you return a range that =E2=80=9Cadapts=E2=80=9D the vector<unique_ptr<T=
>> by calling .get() on the instances, you=E2=80=99re done.
I used Boost.Range but I think that with the Niebler's library it would be =
as simple as:
auto getSubset(int i) const { return _v | view::slice(i, _v.size()) | view:=
:transform(&unique_ptr<T>::get); }; }
This also nicely decouples your clients from the fact that you=E2=80=99re u=
sing a vector.
So I think this problem will be solved when we=E2=80=99ll have ranges.
That said, if in general reinterpret_cast from unique_ptr<T> to T* was not =
undefined behavior,
it would be great. (Or am I missing something here?)
Bye,
Nicola
=20
--=20
---=20
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 e=
mail 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-proposa=
ls/.
--Apple-Mail=_DDF4DB73-BB2D-4820-B048-D59826A07651
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">Il giorno 15/gen/201=
5, alle ore 00:55, Matthew Fioravante <<a href=3D"mailto:fmatthew5876@gm=
ail.com" class=3D"">fmatthew5876@gmail.com</a>> ha scritto:</div><br cla=
ss=3D"Apple-interchange-newline"><div class=3D""><div dir=3D"ltr" class=3D"=
"><div class=3D""> We have unique_ptr<T[]> and vector<unique_=
ptr<T>> but there is one big use case where both are inadequate.</=
div><div class=3D""> </div><div class=3D""> </div><div style=3D"b=
order: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-colo=
r: rgb(250, 250, 250);" class=3D"prettyprint"><code class=3D"prettyprint"><=
font color=3D"#000088" class=3D"">struct</font> <span style=3D"color: rgb(1=
02, 0, 102);" class=3D"styled-by-prettify">FooSlow</span> <span style=3D"co=
lor: rgb(102, 102, 0);" class=3D"styled-by-prettify">{</span><br class=3D""=
> std<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pret=
tify">::</span>vector<span style=3D"color: rgb(102, 102, 0);" class=3D"styl=
ed-by-prettify"><</span>T<span style=3D"color: rgb(102, 102, 0);" class=
=3D"styled-by-prettify">*></span> getSubset<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">int</span> i<span style=3D"color:=
rgb(102, 102, 0);" class=3D"styled-by-prettify">)</span> <span style=3D"co=
lor: rgb(0, 0, 136);" class=3D"styled-by-prettify">const</span> <span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">{</span> <span s=
tyle=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">return</span> =
<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">{</sp=
an> _v<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=
">begin</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-p=
rettify">()</span> <span style=3D"color: rgb(102, 102, 0);" class=3D"styled=
-by-prettify">+</span> i<span style=3D"color: rgb(102, 102, 0);" class=3D"s=
tyled-by-prettify">,</span> _v<span style=3D"color: rgb(102, 102, 0);" clas=
s=3D"styled-by-prettify">.</span><span style=3D"color: rgb(0, 0, 136);" cla=
ss=3D"styled-by-prettify">end</span><span style=3D"color: rgb(102, 102, 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(102=
, 102, 0);" class=3D"styled-by-prettify">}</span><br class=3D""><font color=
=3D"#666600" class=3D""><span style=3D"" class=3D"styled-by-prettify"> =
; std</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pre=
ttify">::</span><span style=3D"" class=3D"styled-by-prettify">vector</span>=
<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify"><<=
/span><span style=3D"" class=3D"styled-by-prettify">std</span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">::</span><span s=
tyle=3D"" class=3D"styled-by-prettify">unique_ptr</span><span style=3D"colo=
r: rgb(102, 102, 0);" class=3D"styled-by-prettify"><</span><span style=
=3D"" class=3D"styled-by-prettify">T</span><span style=3D"color: rgb(102, 1=
02, 0);" class=3D"styled-by-prettify">>></span><span style=3D"" class=
=3D"styled-by-prettify"> _v</span><span style=3D"color: rgb(102, 102, 0);" =
class=3D"styled-by-prettify">;</span><span style=3D"" class=3D"styled-by-pr=
ettify"><br class=3D""></span><span style=3D"color: rgb(102, 102, 0);" clas=
s=3D"styled-by-prettify">};</span><span style=3D"" class=3D"styled-by-prett=
ify"><br class=3D""><br class=3D""></span><span style=3D"color: rgb(0, 0, 1=
36);" class=3D"styled-by-prettify">struct</span><span style=3D"" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: rgb(102, 0, 102);" class=
=3D"styled-by-prettify">FooFast</span><span style=3D"" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-b=
y-prettify">{</span><span style=3D"" class=3D"styled-by-prettify"><br class=
=3D""> carray_view</span><span style=3D"color: rgb(102, 102, 0);" cla=
ss=3D"styled-by-prettify"><</span><span style=3D"" class=3D"styled-by-pr=
ettify">T</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by=
-prettify">*></span><span style=3D"" class=3D"styled-by-prettify"> getSu=
bset</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pret=
tify">(</span><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-pre=
ttify">int</span><span style=3D"" class=3D"styled-by-prettify"> i</span><sp=
an style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">)</span>=
<span style=3D"" class=3D"styled-by-prettify"> </span><span style=3D"color:=
rgb(0, 0, 136);" class=3D"styled-by-prettify">const</span><span style=3D""=
class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(102, 102, 0=
);" class=3D"styled-by-prettify">{</span><span style=3D"" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-=
by-prettify">return</span><span style=3D"" class=3D"styled-by-prettify"> </=
span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">=
{</span><span style=3D"" class=3D"styled-by-prettify"> _v</span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">.</span><span st=
yle=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">begin</span><sp=
an style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">()</span=
><span style=3D"" class=3D"styled-by-prettify"> </span><span style=3D"color=
: rgb(102, 102, 0);" class=3D"styled-by-prettify">+</span><span style=3D"" =
class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 102, 102)=
;" class=3D"styled-by-prettify">1</span><span style=3D"color: rgb(102, 102,=
0);" class=3D"styled-by-prettify">,</span><span style=3D"" class=3D"styled=
-by-prettify"> _v</span><span style=3D"color: rgb(102, 102, 0);" class=3D"s=
tyled-by-prettify">.</span><span style=3D"color: rgb(0, 0, 136);" class=3D"=
styled-by-prettify">end</span><span style=3D"color: rgb(102, 102, 0);" clas=
s=3D"styled-by-prettify">()</span><span style=3D"" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pr=
ettify">};</span><span style=3D"" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">}</span><=
span style=3D"" class=3D"styled-by-prettify"><br class=3D""> std</spa=
n><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">::<=
/span><span style=3D"" class=3D"styled-by-prettify">vector</span><span styl=
e=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify"><</span><spa=
n style=3D"" class=3D"styled-by-prettify">T</span><span style=3D"color: rgb=
(102, 102, 0);" class=3D"styled-by-prettify">*></span><span style=3D"" c=
lass=3D"styled-by-prettify"> _v</span><span style=3D"color: rgb(102, 102, 0=
);" class=3D"styled-by-prettify">;</span><span style=3D"" class=3D"styled-b=
y-prettify"><br class=3D""><br class=3D""> </span><span style=3D"colo=
r: rgb(102, 102, 0);" class=3D"styled-by-prettify">~</span><span style=3D"c=
olor: rgb(102, 0, 102);" class=3D"styled-by-prettify">FooFast</span><span s=
tyle=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">()</span><sp=
an style=3D"" class=3D"styled-by-prettify"> </span><span style=3D"color: rg=
b(102, 102, 0);" class=3D"styled-by-prettify">{</span><span style=3D"" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 0, 136);" cla=
ss=3D"styled-by-prettify">while</span><span style=3D"color: rgb(102, 102, 0=
);" class=3D"styled-by-prettify">(!</span><span style=3D"" class=3D"styled-=
by-prettify">_v</span><span style=3D"color: rgb(102, 102, 0);" class=3D"sty=
led-by-prettify">.</span><span style=3D"" class=3D"styled-by-prettify">empt=
y</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettif=
y">())</span><span style=3D"" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">{</span><span=
style=3D"" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(=
0, 0, 136);" class=3D"styled-by-prettify">delete</span><span style=3D"" cla=
ss=3D"styled-by-prettify"> v</span><span style=3D"color: rgb(102, 102, 0);"=
class=3D"styled-by-prettify">.</span><span style=3D"" class=3D"styled-by-p=
rettify">back</span><span style=3D"color: rgb(102, 102, 0);" class=3D"style=
d-by-prettify">();</span><span style=3D"" class=3D"styled-by-prettify"> v</=
span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">=
..</span><span style=3D"" class=3D"styled-by-prettify">pop_back</span><span =
style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">();</span><=
span style=3D"" class=3D"styled-by-prettify"> </span><span style=3D"color: =
rgb(102, 102, 0);" class=3D"styled-by-prettify">}</span><span style=3D"" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: rgb(102, 102, 0);"=
class=3D"styled-by-prettify">}</span><span style=3D"" class=3D"styled-by-p=
rettify"><br class=3D""></span><span style=3D"color: rgb(102, 102, 0);" cla=
ss=3D"styled-by-prettify">};</span><span style=3D"" class=3D"styled-by-pret=
tify"><br class=3D""></span></font><br class=3D""></code></div><div class=
=3D""><br class=3D"">Here we have a linear array of pointers in our Foo obj=
ect and want to return a view to a subsection of the array. With vector<=
unique_ptr<T>>, we are forced to create a copy because of the type=
system.</div><div class=3D""> </div><div class=3D"">With vector<T*=
>, we can directly return a view referencing a subset but now we have to=
take care of copy(), copy=3D, move(), move=3D, and the dest=
ructor.</div><div class=3D""> </div><div class=3D"">Has there been any=
talk about a managed vector of pointers?</div><div class=3D"">Having a std=
::ptr_vector<T*> or something similar which has the same operations a=
s vector but cleans up the underlying memory would fix this issue.</div><di=
v class=3D""> </div><div style=3D"border: 1px solid rgb(187, 187, 187)=
; word-wrap: break-word; background-color: rgb(250, 250, 250);" class=3D"pr=
ettyprint"><code class=3D"prettyprint"><span style=3D"color: rgb(0, 0, 136)=
;" class=3D"styled-by-prettify">struct</span> <span style=3D"color: rgb(102=
, 0, 102);" class=3D"styled-by-prettify">FooFast</span> <span style=3D"colo=
r: rgb(102, 102, 0);" class=3D"styled-by-prettify">{</span><br class=3D"">&=
nbsp; carray_view<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-b=
y-prettify"><</span>T<span style=3D"color: rgb(102, 102, 0);" class=3D"s=
tyled-by-prettify">*></span> getSubset<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">int</span> i<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">const</span> <span style=3D"c=
olor: rgb(102, 102, 0);" class=3D"styled-by-prettify">{</span> <span style=
=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">return</span> <spa=
n style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">{</span> =
_v<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">be=
gin</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prett=
ify">()</span> <span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-=
prettify">+</span> <span style=3D"color: rgb(0, 102, 102);" class=3D"styled=
-by-prettify">1</span><span style=3D"color: rgb(102, 102, 0);" class=3D"sty=
led-by-prettify">,</span> _v<span style=3D"color: rgb(102, 102, 0);" class=
=3D"styled-by-prettify">.</span><span style=3D"color: rgb(0, 0, 136);" clas=
s=3D"styled-by-prettify">end</span><span style=3D"color: rgb(102, 102, 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(102,=
102, 0);" class=3D"styled-by-prettify">}</span><br class=3D""> std<s=
pan style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">::</spa=
n>ptr_vector<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pre=
ttify"><</span>T<span style=3D"color: rgb(102, 102, 0);" class=3D"styled=
-by-prettify">*></span> _v<span style=3D"color: rgb(102, 102, 0);" class=
=3D"styled-by-prettify">;</span><br class=3D""><span style=3D"color: rgb(10=
2, 102, 0);" class=3D"styled-by-prettify">};</span></code></div><div class=
=3D""> <br class=3D"webkit-block-placeholder"></div><div class=3D"">An=
other alternative would be to have some guarantee in the standard that rein=
terpret_cast<T*>(std::unique_ptr<T>()) is valid. That is that a=
unique_ptr with default deleter is exactly the same as raw pointer in term=
s of memory layout and we can do some ugly casting.</div><div class=3D"">&n=
bsp;</div><div class=3D""><div style=3D"border: 1px solid rgb(187, 187, 187=
); word-wrap: break-word; background-color: rgb(250, 250, 250);" class=3D"p=
rettyprint"><code class=3D"prettyprint"><span style=3D"color: rgb(0, 0, 136=
);" class=3D"styled-by-prettify">template</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">typename</span> T<span styl=
e=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">></span><br =
class=3D"">T<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pre=
ttify">**</span> unique_ptr_cast<span style=3D"color: rgb(102, 102, 0);" cl=
ass=3D"styled-by-prettify"><</span>T<span style=3D"color: rgb(102, 102, =
0);" class=3D"styled-by-prettify">>(</span>unique_ptr<span style=3D"colo=
r: rgb(102, 102, 0);" class=3D"styled-by-prettify"><</span>T<span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">>*</span> ptr=
<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">)</sp=
an> <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"=
>return</span> <span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-pr=
ettify">reinterpret_cast</span><span style=3D"color: rgb(102, 102, 0);" cla=
ss=3D"styled-by-prettify"><</span>T<span style=3D"color: rgb(102, 102, 0=
);" class=3D"styled-by-prettify">**>(</span>ptr<span style=3D"color: rgb=
(102, 102, 0);" class=3D"styled-by-prettify">);</span> <span style=3D"color=
: rgb(102, 102, 0);" class=3D"styled-by-prettify">}</span><br class=3D""><b=
r class=3D""><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-pret=
tify">struct</span> <span style=3D"color: rgb(102, 0, 102);" class=3D"style=
d-by-prettify">FooFast</span> <span style=3D"color: rgb(102, 102, 0);" clas=
s=3D"styled-by-prettify">{</span><br class=3D""> carray_view<span styl=
e=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify"><</span>T<sp=
an style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">*></s=
pan> getSubset<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-p=
rettify">(</span><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-=
prettify">int</span> i<span style=3D"color: rgb(102, 102, 0);" class=3D"sty=
led-by-prettify">)</span> <span style=3D"color: rgb(0, 0, 136);" class=3D"s=
tyled-by-prettify">const</span> <span style=3D"color: rgb(102, 102, 0);" cl=
ass=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(102, 1=
02, 0);" class=3D"styled-by-prettify">{</span> unique_ptr_cast<span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">(</span>_v<span =
style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">.</span>dat=
a<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">()</=
span> <span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify"=
>+</span> i<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pret=
tify">),</span> unique_ptr_cast<span style=3D"color: rgb(102, 102, 0);" cla=
ss=3D"styled-by-prettify">(</span>_v<span style=3D"color: rgb(102, 102, 0);=
" class=3D"styled-by-prettify">.</span>data<span style=3D"color: rgb(102, 1=
02, 0);" class=3D"styled-by-prettify">()</span> <span style=3D"color: rgb(1=
02, 102, 0);" class=3D"styled-by-prettify">+</span> v<span style=3D"color: =
rgb(102, 102, 0);" class=3D"styled-by-prettify">.</span>size<span style=3D"=
color: rgb(102, 102, 0);" class=3D"styled-by-prettify">())</span> <span sty=
le=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">};</span> <spa=
n style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">}</span><=
br class=3D""> std<span style=3D"color: rgb(102, 102, 0);" class=3D"st=
yled-by-prettify">::</span>vector<span style=3D"color: rgb(102, 102, 0);" c=
lass=3D"styled-by-prettify"><</span>std<span style=3D"color: rgb(102, 10=
2, 0);" class=3D"styled-by-prettify">::</span>unique_ptr<span style=3D"colo=
r: rgb(102, 102, 0);" class=3D"styled-by-prettify"><</span>T<span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">*>></span>=
_v<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">;<=
/span><br class=3D""><span style=3D"color: rgb(102, 102, 0);" class=3D"styl=
ed-by-prettify">};</span></code></div><span style=3D"color: rgb(102, 102, 0=
);" class=3D"styled-by-prettify"><br class=3D"">Thoughts?</span></div><div =
class=3D""><br class=3D""></div></div></div></blockquote><div><br class=3D"=
"></div><div>Hi.</div><div>I had a similar design problem recently but I so=
lved it with ranges.</div><div><br class=3D""></div><div>If you return a ra=
nge that =E2=80=9Cadapts=E2=80=9D the vector<unique_ptr<T>> by =
calling .get() on the instances, you=E2=80=99re done.</div><div><br class=
=3D""></div><div>I used Boost.Range but I think that with the Niebler's lib=
rary it would be as simple as:</div><div><br class=3D""></div><div>auto get=
Subset(int i) const { return _v | view::slice(i, _v.size()) | view::transfo=
rm(&unique_ptr<T>::get); }; }</div><div><br class=3D""></div><div=
>This also nicely decouples your clients from the fact that you=E2=80=99re =
using a vector.</div><div><br class=3D""></div><div>So I think this problem=
will be solved when we=E2=80=99ll have ranges.</div><div><br class=3D""></=
div><div>That said, if in general reinterpret_cast from unique_ptr<T>=
to T* was not undefined behavior,</div><div>it would be great. (Or am I mi=
ssing something here?)</div><div><br class=3D""></div><div>Bye,</div><div>N=
icola</div><div><br class=3D""></div><div> </div></div><br class=3D"">=
</body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
--Apple-Mail=_DDF4DB73-BB2D-4820-B048-D59826A07651--
.
Author: Nicola Gigante <nicola.gigante@gmail.com>
Date: Thu, 15 Jan 2015 16:49:58 +0100
Raw View
--Apple-Mail=_8C1FB73C-DA31-4A21-8F5D-796F9A974D67
Content-Type: text/plain; charset=UTF-8
> Il giorno 15/gen/2015, alle ore 16:46, Nicola Gigante <nicola.gigante@gmail.com> ha scritto:
>
> That said, if in general reinterpret_cast from unique_ptr<T> to T* was not undefined behavior,
> it would be great. (Or am I missing something here?)
>
I meant from unique_ptr<T>* to T**, of course.
Bye,
Nicola
--
---
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/.
--Apple-Mail=_8C1FB73C-DA31-4A21-8F5D-796F9A974D67
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dus-ascii"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode=
: space; -webkit-line-break: after-white-space;" class=3D""><br class=3D"">=
<div><blockquote type=3D"cite" class=3D""><div class=3D"">Il giorno 15/gen/=
2015, alle ore 16:46, Nicola Gigante <<a href=3D"mailto:nicola.gigante@g=
mail.com" class=3D"">nicola.gigante@gmail.com</a>> ha scritto:</div><br =
class=3D"Apple-interchange-newline"><div class=3D""><div style=3D"font-fami=
ly: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; f=
ont-weight: normal; letter-spacing: normal; line-height: normal; orphans: a=
uto; text-align: start; text-indent: 0px; text-transform: none; white-space=
: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"=
class=3D"">That said, if in general reinterpret_cast from unique_ptr<T&=
gt; to T* was not undefined behavior,</div><div style=3D"font-family: Helve=
tica; font-size: 12px; font-style: normal; font-variant: normal; font-weigh=
t: normal; letter-spacing: normal; line-height: normal; orphans: auto; text=
-align: start; text-indent: 0px; text-transform: none; white-space: normal;=
widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D=
"">it would be great. (Or am I missing something here?)</div><div style=3D"=
font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: =
normal; font-weight: normal; letter-spacing: normal; line-height: normal; o=
rphans: auto; text-align: start; text-indent: 0px; text-transform: none; wh=
ite-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-wid=
th: 0px;" class=3D""><br class=3D""></div></div></blockquote><div><br class=
=3D""></div><div>I meant from unique_ptr<T>* to T**, of course.</div>=
<br class=3D""><div class=3D""><div style=3D"font-family: Helvetica; font-s=
ize: 12px; font-style: normal; font-variant: normal; font-weight: normal; l=
etter-spacing: normal; line-height: normal; orphans: auto; text-align: star=
t; text-indent: 0px; text-transform: none; white-space: normal; widows: aut=
o; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D"">Bye,</div=
><div style=3D"font-family: Helvetica; font-size: 12px; font-style: normal;=
font-variant: normal; font-weight: normal; letter-spacing: normal; line-he=
ight: normal; orphans: auto; text-align: start; text-indent: 0px; text-tran=
sform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-=
text-stroke-width: 0px;" class=3D"">Nicola</div></div></div><br class=3D"">=
</body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
--Apple-Mail=_8C1FB73C-DA31-4A21-8F5D-796F9A974D67--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 15 Jan 2015 17:52:40 +0200
Raw View
On 15 January 2015 at 17:49, Nicola Gigante <nicola.gigante@gmail.com> wrote:
>
> Il giorno 15/gen/2015, alle ore 16:46, Nicola Gigante
> <nicola.gigante@gmail.com> ha scritto:
>
> That said, if in general reinterpret_cast from unique_ptr<T> to T* was not
> undefined behavior,
> it would be great. (Or am I missing something here?)
>
>
> I meant from unique_ptr<T>* to T**, of course.
Sounds like such a conversion would create another opportunity to run
into the situation
described in
http://www.stroustrup.com/bs_faq2.html#conversion
--
---
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/.
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Thu, 15 Jan 2015 08:03:44 -0800 (PST)
Raw View
------=_Part_148_2032516218.1421337824980
Content-Type: multipart/alternative;
boundary="----=_Part_149_477703097.1421337824980"
------=_Part_149_477703097.1421337824980
Content-Type: text/plain; charset=UTF-8
Enter code here...
Enter code here...
On Thursday, January 15, 2015 at 10:46:34 AM UTC-5, Nicola Gigante wrote:
>
> That said, if in general reinterpret_cast from unique_ptr<T> to T* was not
> undefined behavior,
> it would be great. (Or am I missing something here?)
>
>
There are other cases where this kind of aliasing would be helpful:
extern "C" graphics_api_render(float* xyzw_points, size_t count);
struct Vec4 {
float x, y, z, w;
};
vec4 v[256];
//Fill in the vectors
//Pass to graphics API
graphics_api_render(reinterpret_cast<float*>(v), 256);
I'm not sure if it would be worth looking into adding a "user defined
aliasing" feature to be able to do this portably and ensure correctness via
the compiler.
Something like this:
//Specialization for default unique_ptr
template <typename T>
unique_ptr<T,std::default_delete<T>) {
alias T*; //Says that we can alias_cast<T**>(this);
};
struct Vec4 {
float x, y, z, w;
alias float; //Says that we can alias_cast<float*>(this);
};
//Concepts: Fails to compile unless T can alias V* via alias keyword
template <typename T, typename V>
T alias_cast(V* obj) { return reinterpret_cast<T>(obj); }
The alias keyword could also be used to poke holes into the strict aliasing
rule. That is if we have a Vec4* and a float*, the compiler may no longer
assume that they do not alias each other.
--
---
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_149_477703097.1421337824980
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div style=3D"border: 1px solid rgb(187, 187, 187); word-w=
rap: break-word; background-color: rgb(250, 250, 250);" class=3D"prettyprin=
t"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D=
"color: rgb(102, 0, 102);" class=3D"styled-by-prettify"><div style=3D"borde=
r: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-color: r=
gb(250, 250, 250);" class=3D"prettyprint"><code class=3D"prettyprint"><div =
class=3D"subprettyprint"><span style=3D"color: rgb(102, 0, 102);" class=3D"=
styled-by-prettify">Enter</span><span style=3D"color: rgb(0, 0, 0);" class=
=3D"styled-by-prettify"> code here</span><span style=3D"color: rgb(102, 102=
, 0);" class=3D"styled-by-prettify">...</span></div></code></div><br>Enter<=
/span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> co=
de here</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-p=
rettify">...</span></div></code></div><br><br>On Thursday, January 15, 2015=
at 10:46:34 AM UTC-5, Nicola Gigante wrote:<blockquote style=3D"margin: 0p=
x 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); =
border-left-width: 1px; border-left-style: solid;" class=3D"gmail_quote"><d=
iv style=3D"word-wrap: break-word;"><div><div>That said, if in general rein=
terpret_cast from unique_ptr<T> to T* was not undefined behavior,</di=
v><div>it would be great. (Or am I missing something here?)</div><div> =
;</div></div></div></blockquote><div> </div><div>There are other cases=
where this kind of aliasing would be helpful:</div><div> </div><div><=
div style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; b=
ackground-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">extern</span><span style=3D"color: rgb(=
0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0=
, 136, 0);" class=3D"styled-by-prettify">"C"</span><span style=3D"color: rg=
b(0, 0, 0);" class=3D"styled-by-prettify"> graphics_api_render</span><span =
style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">(</span><sp=
an style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">float</spa=
n><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"> xyz=
w_points</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"> size_t count</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><br></span><span style=3D"color: rgb(0, 0, 136)=
;" class=3D"styled-by-prettify">struct</span><span style=3D"color: rgb(0, 0=
, 0);" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(102, =
0, 102);" class=3D"styled-by-prettify">Vec4</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: r=
gb(0, 0, 0);" class=3D"styled-by-prettify"><br> </span><span style=3D=
"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">float</span><span sty=
le=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> x</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"> y</span><span =
style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">,</span><sp=
an style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> z</span><sp=
an 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"> w</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></=
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><br>vec4 v</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styl=
ed-by-prettify">[</span><span style=3D"color: rgb(0, 102, 102);" class=3D"s=
tyled-by-prettify">256</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></span><span style=3D"color: rgb(136, 0, 0);" c=
lass=3D"styled-by-prettify">//Fill in the vectors</span><span style=3D"colo=
r: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br><br></span><span style=
=3D"color: rgb(136, 0, 0);" class=3D"styled-by-prettify">//Pass to graphics=
API</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify=
"><br>graphics_api_render</span><span style=3D"color: rgb(102, 102, 0);" cl=
ass=3D"styled-by-prettify">(</span><span style=3D"color: rgb(0, 0, 136);" c=
lass=3D"styled-by-prettify">reinterpret_cast</span><span style=3D"color: rg=
b(102, 102, 0);" class=3D"styled-by-prettify"><</span><span style=3D"col=
or: rgb(0, 0, 136);" class=3D"styled-by-prettify">float</span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">*>(</span><sp=
an style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">v</span><spa=
n 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, 102, 102);" class=3D"styled-by-prettify">256</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>I'm not sure if it would be worth looking =
into adding a "user defined aliasing" feature to be able to do this po=
rtably and ensure correctness via the compiler.</div><div> </div><div>=
Something like this:</div><div> </div><div><div style=3D"border: 1px s=
olid 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, 0);" class=3D"styled-by-pr=
ettify"><br>//Specialization for default unique_ptr<br>template <typenam=
e T><br>unique_ptr<T,std::default_delete<T>) {<br> alias =
T*; //Says that we can alias_cast<T**>(this);<br>};<br><br>struct Vec=
4 {<br> float x, y, z, w;<br> alias float; //Says that we can a=
lias_cast<float*>(this);<br>};<br><br><span style=3D"color: rgb(0, 0,=
0);" class=3D"styled-by-prettify">//Concepts: Fails to compile unless T ca=
n alias V* via alias keyword<br>template <typename T, typename V><br>=
T alias_cast(V* obj) { return reinterpret_cast<T>(obj); }</span></spa=
n></div></code></div><br>The alias keyword could also be used to poke holes=
into the strict aliasing rule. That is if we have a Vec4* and a float*, th=
e compiler may no longer assume that they do not alias each other.</div></d=
iv>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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_149_477703097.1421337824980--
------=_Part_148_2032516218.1421337824980--
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Thu, 15 Jan 2015 14:18:20 -0800 (PST)
Raw View
------=_Part_211_2041404718.1421360300292
Content-Type: multipart/alternative;
boundary="----=_Part_212_1690350954.1421360300292"
------=_Part_212_1690350954.1421360300292
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
=20
On Thursday, January 15, 2015 at 10:46:34 AM UTC-5, Nicola Gigante wrote:
>
>
> =20
> If you return a range that =E2=80=9Cadapts=E2=80=9D the vector<unique_ptr=
<T>> by calling=20
> .get() on the instances, you=E2=80=99re done.
>
> I used Boost.Range but I think that with the Niebler's library it would b=
e=20
> as simple as:
>
> auto getSubset(int i) const { return _v | view::slice(i, _v.size()) |=20
> view::transform(&unique_ptr<T>::get); }; }
>
> This also nicely decouples your clients from the fact that you=E2=80=99re=
using a=20
> vector.
>
> So I think this problem will be solved when we=E2=80=99ll have ranges.
>
=20
=20
Adapting ranges don't actually solve it for me, I'll show more of my use=20
case:
=20
struct Foo {
vector<T*> inputs; //Owned by someone else
vector<std::vector<T*>> stages; //Owned by us
=20
array_view<T*> getInputs() { return inputs; }
array_view<T*> getOutputs() {
return stages.empty() ? getInputs() : stages.back()
}
~Foo() { for(auto& s: stages) for(auto& t: s) delete s; }
};
=20
In this situation I'm really forced to manage the memory myself because=20
std::unique_ptr<T> and T* are different types. If we could portably alias=
=20
unique_ptr<T>* to T**, then I could take advantage of the automatic memory=
=20
management.
--=20
---=20
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 e=
mail 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-proposa=
ls/.
------=_Part_212_1690350954.1421360300292
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><code class=3D"prettyprint"><div class=3D"subprettyprint">=
<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify"></spa=
n> </div></code><br><br>On Thursday, January 15, 2015 at 10:46:34 AM U=
TC-5, Nicola Gigante wrote:<blockquote style=3D"margin: 0px 0px 0px 0.8ex; =
padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-width=
: 1px; border-left-style: solid;" class=3D"gmail_quote"><div style=3D"word-=
wrap: break-word;"><div><div><br> </div><div>If you return a range tha=
t =E2=80=9Cadapts=E2=80=9D the vector<unique_ptr<T>> by calling=
.get() on the instances, you=E2=80=99re done.</div><div><br></div><div>I u=
sed Boost.Range but I think that with the Niebler's library it would be as =
simple as:</div><div><br></div><div>auto getSubset(int i) const { return _v=
| view::slice(i, _v.size()) | view::transform(&unique_ptr<T><wbr=
>::get); }; }</div><div><br></div><div>This also nicely decouples your clie=
nts from the fact that you=E2=80=99re using a vector.</div><div><br></div><=
div>So I think this problem will be solved when we=E2=80=99ll have ranges.<=
/div></div></div></blockquote><div> </div><div> </div><div>Adapti=
ng ranges don't actually solve it for me, I'll show more of my use case:</d=
iv><div> </div><div style=3D"border: 1px solid rgb(187, 187, 187); wor=
d-wrap: break-word; background-color: rgb(250, 250, 250);" class=3D"prettyp=
rint"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">struct</span><span=
style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span =
style=3D"color: rgb(102, 0, 102);" class=3D"styled-by-prettify">Foo</span><=
span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </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>&nbs=
p; vector</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"styl=
ed-by-prettify">*></span><span style=3D"color: rgb(0, 0, 0);" class=3D"s=
tyled-by-prettify"> inputs</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"> </span><span style=3D"color: rgb(136, 0, 0);" c=
lass=3D"styled-by-prettify">//Owned by someone else</span><span style=3D"co=
lor: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br> vector</span><s=
pan 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">std</=
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">=
vector</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-=
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"> stages</span><span style=3D"color: rgb(102, 102, 0);" =
class=3D"styled-by-prettify">;</span><span style=3D"color: rgb(0, 0, 0);" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: rgb(136, 0, 0);" =
class=3D"styled-by-prettify">//Owned by us</span><span style=3D"color: rgb(=
0, 0, 0);" class=3D"styled-by-prettify"><br> <br> array_view</s=
pan><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, 102, 0);" class=3D"styled-by-pretti=
fy">*></span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pre=
ttify"> getInputs</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"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"> inputs</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"><br> array_view</span><span st=
yle=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify"><</span><s=
pan style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">T</span><sp=
an 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"> getO=
utputs</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-pr=
ettify"> </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> </span><span style=3D"color: rgb(0, 0, 136);" c=
lass=3D"styled-by-prettify">return</span><span style=3D"color: rgb(0, 0, 0)=
;" class=3D"styled-by-prettify"> stages</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">empty</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(102, 102, 0);" class=3D"styled-by-prettify">?</span><span style=3D"co=
lor: rgb(0, 0, 0);" class=3D"styled-by-prettify"> getInputs</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"> </span><span =
style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">:</span><sp=
an style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> stages</spa=
n><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">back=
</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> </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"styled=
-by-prettify"><br> </span><span style=3D"color: rgb(102, 102, 0);" cl=
ass=3D"styled-by-prettify">~</span><span style=3D"color: rgb(102, 0, 102);"=
class=3D"styled-by-prettify">Foo</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, 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(0, 0=
, 136);" class=3D"styled-by-prettify">for</span><span style=3D"color: rgb(1=
02, 102, 0);" class=3D"styled-by-prettify">(</span><span style=3D"color: rg=
b(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"> s</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"> stages</span><sp=
an 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">for</spa=
n><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">au=
to</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pretti=
fy">&</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pre=
ttify"> 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"> s</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">delete</span><span style=3D"color: rgb(0, 0, 0);" class=3D"st=
yled-by-prettify"> s</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);" cl=
ass=3D"styled-by-prettify">}</span><span style=3D"color: rgb(0, 0, 0);" cla=
ss=3D"styled-by-prettify"><br></span><span style=3D"color: rgb(102, 102, 0)=
;" class=3D"styled-by-prettify">};</span></div></code></div><p> </p><d=
iv>In this situation I'm really forced to manage the memory myself because =
std::unique_ptr<T> and T* are different types. If we could portably a=
lias unique_ptr<T>* to T**, then I could take advantage of the automa=
tic memory management.</div><div><br></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" 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_212_1690350954.1421360300292--
------=_Part_211_2041404718.1421360300292--
.
Author: =?UTF-8?Q?David_Rodr=C3=ADguez_Ibeas?= <dibeas@ieee.org>
Date: Fri, 16 Jan 2015 10:30:48 -0500
Raw View
--047d7bacc0622d251c050cc6a8e5
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Not ideal, but you could have an additional member:
vector<T*> current;
And have it initialized with 'inputs' and updated with the current view of
the data whenever a stage completes... If you don't need to go back to the
inputs after the first stage completes, you could reuse the 'inputs' member=
..
Regarding the aliasing of 'unique_ptr<T>*' with 'T**' (or even 'T *const
*'), the problem is that this makes sense only for specializations of
'std::unique_ptr<T,D>' with stateless deleters, and would probably be
confusing (why is it sometimes "convertible", sometimes not) or dangerous
(reinterpreting the deleter as a 'T*').
David
On Thu, Jan 15, 2015 at 5:18 PM, Matthew Fioravante <fmatthew5876@gmail.com=
>
wrote:
>
>
>
> On Thursday, January 15, 2015 at 10:46:34 AM UTC-5, Nicola Gigante wrote:
>>
>>
>>
>> If you return a range that =E2=80=9Cadapts=E2=80=9D the vector<unique_pt=
r<T>> by calling
>> .get() on the instances, you=E2=80=99re done.
>>
>> I used Boost.Range but I think that with the Niebler's library it would
>> be as simple as:
>>
>> auto getSubset(int i) const { return _v | view::slice(i, _v.size()) |
>> view::transform(&unique_ptr<T>::get); }; }
>>
>> This also nicely decouples your clients from the fact that you=E2=80=99r=
e using a
>> vector.
>>
>> So I think this problem will be solved when we=E2=80=99ll have ranges.
>>
>
>
> Adapting ranges don't actually solve it for me, I'll show more of my use
> case:
>
> struct Foo {
> vector<T*> inputs; //Owned by someone else
> vector<std::vector<T*>> stages; //Owned by us
>
> array_view<T*> getInputs() { return inputs; }
> array_view<T*> getOutputs() {
> return stages.empty() ? getInputs() : stages.back()
> }
> ~Foo() { for(auto& s: stages) for(auto& t: s) delete s; }
> };
>
>
> In this situation I'm really forced to manage the memory myself because
> std::unique_ptr<T> and T* are different types. If we could portably alias
> unique_ptr<T>* to T**, then I could take advantage of the automatic memor=
y
> management.
>
> --
>
> ---
> 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/.
>
--=20
---=20
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 e=
mail 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-proposa=
ls/.
--047d7bacc0622d251c050cc6a8e5
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Not ideal, but you could have an additional member:<br><br=
>vector<T*> current;<br><br>And have it initialized with 'inputs&=
#39; and updated with the current view of the data whenever a stage complet=
es... If you don't need to go back to the inputs after the first stage =
completes, you could reuse the 'inputs' member.<br><br>Regarding th=
e aliasing of 'unique_ptr<T>*' with 'T**' (or even &#=
39;T *const *'), the problem is that this makes sense only for speciali=
zations of 'std::unique_ptr<T,D>' with stateless deleters, an=
d would probably be confusing (why is it sometimes "convertible",=
sometimes not) or dangerous (reinterpreting the deleter as a 'T*')=
..<br><br>David</div><div class=3D"gmail_extra"><br><div class=3D"gmail_quot=
e">On Thu, Jan 15, 2015 at 5:18 PM, Matthew Fioravante <span dir=3D"ltr">&l=
t;<a href=3D"mailto:fmatthew5876@gmail.com" target=3D"_blank">fmatthew5876@=
gmail.com</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><span class=3D""><code><div><span style=3D"color:rgb(102,102,0)"><=
/span>=C2=A0</div></code><br><br>On Thursday, January 15, 2015 at 10:46:34 =
AM UTC-5, Nicola Gigante wrote:</span><span class=3D""><blockquote style=3D=
"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,20=
4);border-left-width:1px;border-left-style:solid" class=3D"gmail_quote"><di=
v style=3D"word-wrap:break-word"><div><div><br>=C2=A0</div><div>If you retu=
rn a range that =E2=80=9Cadapts=E2=80=9D the vector<unique_ptr<T>&=
gt; by calling .get() on the instances, you=E2=80=99re done.</div><div><br>=
</div><div>I used Boost.Range but I think that with the Niebler's libra=
ry it would be as simple as:</div><div><br></div><div>auto getSubset(int i)=
const { return _v | view::slice(i, _v.size()) | view::transform(&uniqu=
e_ptr<T><u></u>::get); }; }</div><div><br></div><div>This also nicely=
decouples your clients from the fact that you=E2=80=99re using a vector.</=
div><div><br></div><div>So I think this problem will be solved when we=E2=
=80=99ll have ranges.</div></div></div></blockquote><div>=C2=A0</div><div>=
=C2=A0</div></span><div>Adapting ranges don't actually solve it for me,=
I'll show more of my use case:</div><div>=C2=A0</div><div style=3D"bor=
der:1px solid rgb(187,187,187);word-wrap:break-word;background-color:rgb(25=
0,250,250)"><code><div><span style=3D"color:rgb(0,0,136)">struct</span><spa=
n style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,102)">F=
oo</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(=
102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 vector</spa=
n><span style=3D"color:rgb(102,102,0)"><</span><span style=3D"color:rgb(=
0,0,0)">T</span><span style=3D"color:rgb(102,102,0)">*></span><span styl=
e=3D"color:rgb(0,0,0)"> inputs</span><span style=3D"color:rgb(102,102,0)">;=
</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(13=
6,0,0)">//Owned by someone else</span><span style=3D"color:rgb(0,0,0)"><br>=
=C2=A0 vector</span><span style=3D"color:rgb(102,102,0)"><</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)">vector</span><span style=3D"color:r=
gb(102,102,0)"><</span><span style=3D"color:rgb(0,0,0)">T</span><span st=
yle=3D"color:rgb(102,102,0)">*>></span><span style=3D"color:rgb(0,0,0=
)"> stages</span><span style=3D"color:rgb(102,102,0)">;</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(136,0,0)">//Owned by=
us</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 <br>=C2=A0 array_view=
</span><span style=3D"color:rgb(102,102,0)"><</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)"> getInputs</span><span style=3D"color:rgb(102,1=
02,0)">()</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"col=
or:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"> </span><span s=
tyle=3D"color:rgb(0,0,136)">return</span><span style=3D"color:rgb(0,0,0)"> =
inputs</span><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"co=
lor:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">}</span><span =
style=3D"color:rgb(0,0,0)"><br>=C2=A0 array_view</span><span style=3D"color=
:rgb(102,102,0)"><</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)"=
> getOutputs</span><span style=3D"color:rgb(102,102,0)">()</span><span styl=
e=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">{</span=
><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"c=
olor:rgb(0,0,136)">return</span><span style=3D"color:rgb(0,0,0)"> stages</s=
pan><span style=3D"color:rgb(102,102,0)">.</span><span style=3D"color:rgb(0=
,0,0)">empty</span><span style=3D"color:rgb(102,102,0)">()</span><span styl=
e=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">?</span=
><span style=3D"color:rgb(0,0,0)"> getInputs</span><span 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><span style=3D"color:rgb(0,0,0)"> stages<=
/span><span style=3D"color:rgb(102,102,0)">.</span><span style=3D"color:rgb=
(0,0,0)">back</span><span style=3D"color:rgb(102,102,0)">()</span><span sty=
le=3D"color:rgb(0,0,0)"><br>=C2=A0 </span><span style=3D"color:rgb(102,102,=
0)">}</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 </span><span style=
=3D"color:rgb(102,102,0)">~</span><span style=3D"color:rgb(102,0,102)">Foo<=
/span><span style=3D"color:rgb(102,102,0)">()</span><span style=3D"color:rg=
b(0,0,0)"> </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)">for</span>=
<span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,1=
36)">auto</span><span style=3D"color:rgb(102,102,0)">&</span><span styl=
e=3D"color:rgb(0,0,0)"> s</span><span style=3D"color:rgb(102,102,0)">:</spa=
n><span style=3D"color:rgb(0,0,0)"> stages</span><span style=3D"color:rgb(1=
02,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"=
color:rgb(0,0,136)">for</span><span style=3D"color:rgb(102,102,0)">(</span>=
<span style=3D"color:rgb(0,0,136)">auto</span><span style=3D"color:rgb(102,=
102,0)">&</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)"> s</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)">delete</span><span style=3D"=
color:rgb(0,0,0)"> s</span><span style=3D"color:rgb(102,102,0)">;</span><sp=
an style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">=
}</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rg=
b(102,102,0)">};</span></div></code></div><p>=C2=A0</p><div>In this situati=
on I'm really forced to manage the memory myself because std::unique_pt=
r<T> and T* are different types. If we could portably alias unique_pt=
r<T>* to T**, then I could take advantage of the automatic memory man=
agement.</div><div><br></div></div><div class=3D"HOEnZb"><div class=3D"h5">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
--047d7bacc0622d251c050cc6a8e5--
.
Author: Nicola Gigante <nicola.gigante@gmail.com>
Date: Fri, 16 Jan 2015 18:46:50 +0100
Raw View
--Apple-Mail=_A7F1EF88-4131-45DC-BD1A-FBB1FB1DA128
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
Il giorno 15/gen/2015, alle ore 23:18, Matthew Fioravante <fmatthew5876@gma=
il.com> ha scritto:
>=20
> =20
> Adapting ranges don't actually solve it for me, I'll show more of my use =
case:
> =20
> struct Foo {
> vector<T*> inputs; //Owned by someone else
> vector<std::vector<T*>> stages; //Owned by us
> =20
> array_view<T*> getInputs() { return inputs; }
> array_view<T*> getOutputs() {
> return stages.empty() ? getInputs() : stages.back()
> }
> ~Foo() { for(auto& s: stages) for(auto& t: s) delete s; }
> };
> =20
> In this situation I'm really forced to manage the memory myself because s=
td::unique_ptr<T> and T* are different types. If we could portably alias un=
ique_ptr<T>* to T**, then I could take advantage of the automatic memory ma=
nagement.
>=20
I=E2=80=99m sorry, I don=E2=80=99t get it.
Why can=E2=80=99t you return a view of inputs if stages is empty and return=
a view of stages.back() otherwise?
Bye,
Nicola
--=20
---=20
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 e=
mail 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-proposa=
ls/.
--Apple-Mail=_A7F1EF88-4131-45DC-BD1A-FBB1FB1DA128
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>Il giorn=
o 15/gen/2015, alle ore 23:18, Matthew Fioravante <<a href=3D"mailto:fma=
tthew5876@gmail.com">fmatthew5876@gmail.com</a>> ha scritto:</div><br cl=
ass=3D"Apple-interchange-newline"><blockquote type=3D"cite"><div dir=3D"ltr=
"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"=
color: rgb(102, 102, 0);" class=3D"styled-by-prettify"></span><br></div></c=
ode><div> </div><div>Adapting ranges don't actually solve it for me, I=
'll show more of my use case:</div><div> </div><div style=3D"border: 1=
px solid rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(2=
50, 250, 250); position: static; z-index: auto;" class=3D"prettyprint"><cod=
e class=3D"prettyprint"><span style=3D"color: rgb(0, 0, 136);" class=3D"sty=
led-by-prettify">struct</span> <span style=3D"color: rgb(102, 0, 102);" cla=
ss=3D"styled-by-prettify">Foo</span> <span style=3D"color: rgb(102, 102, 0)=
;" class=3D"styled-by-prettify">{</span><br> vector<span style=3D"col=
or: rgb(102, 102, 0);" class=3D"styled-by-prettify"><</span>T<span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">*></span> inp=
uts<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">;<=
/span> <span style=3D"color: rgb(136, 0, 0);" class=3D"styled-by-prettify">=
//Owned by someone else</span><br> vector<span style=3D"color: rgb(10=
2, 102, 0);" class=3D"styled-by-prettify"><</span>std<span style=3D"colo=
r: rgb(102, 102, 0);" class=3D"styled-by-prettify">::</span>vector<span sty=
le=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify"><</span>T<s=
pan style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">*>&g=
t;</span> stages<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by=
-prettify">;</span> <span style=3D"color: rgb(136, 0, 0);" class=3D"styled-=
by-prettify">//Owned by us</span><br> <br> array_view<span styl=
e=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify"><</span>T<sp=
an style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">*></s=
pan> getInputs<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-p=
rettify">()</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"styl=
ed-by-prettify">return</span> inputs<span style=3D"color: rgb(102, 102, 0);=
" class=3D"styled-by-prettify">;</span> <span style=3D"color: rgb(102, 102,=
0);" class=3D"styled-by-prettify">}</span><br> array_view<span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify"><</span>T<spa=
n style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">*></sp=
an> getOutputs<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-p=
rettify">()</span> <span style=3D"color: rgb(102, 102, 0);" class=3D"styled=
-by-prettify">{</span><br> <span style=3D"color: rgb(0, 0, 136=
);" class=3D"styled-by-prettify">return</span> stages<span style=3D"color: =
rgb(102, 102, 0);" class=3D"styled-by-prettify">.</span>empty<span style=3D=
"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">()</span> <span sty=
le=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">?</span> getIn=
puts<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">(=
)</span> <span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pretti=
fy">:</span> stages<span style=3D"color: rgb(102, 102, 0);" class=3D"styled=
-by-prettify">.</span>back<span style=3D"color: rgb(102, 102, 0);" class=3D=
"styled-by-prettify">()</span><br> <span style=3D"color: rgb(102, 102=
, 0);" class=3D"styled-by-prettify">}</span><br> <span style=3D"color=
: rgb(102, 102, 0);" class=3D"styled-by-prettify">~</span><span style=3D"co=
lor: rgb(102, 0, 102);" class=3D"styled-by-prettify">Foo</span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">()</span> <span =
style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">{</span> <s=
pan style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">for</span=
><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">(</s=
pan><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">aut=
o</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettif=
y">&</span> s<span style=3D"color: rgb(102, 102, 0);" class=3D"styled-b=
y-prettify">:</span> stages<span style=3D"color: rgb(102, 102, 0);" class=
=3D"styled-by-prettify">)</span> <span style=3D"color: rgb(0, 0, 136);" cla=
ss=3D"styled-by-prettify">for</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">auto</span><span style=3D"color: rgb(102, 1=
02, 0);" class=3D"styled-by-prettify">&</span> t<span style=3D"color: r=
gb(102, 102, 0);" class=3D"styled-by-prettify">:</span> s<span style=3D"col=
or: rgb(102, 102, 0);" class=3D"styled-by-prettify">)</span> <span style=3D=
"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">delete</span> s<span =
style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">;</span> <s=
pan style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">}</span=
><br><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">=
};</span></code></div><div> <br class=3D"webkit-block-placeholder"></d=
iv><div>In this situation I'm really forced to manage the memory myself bec=
ause std::unique_ptr<T> and T* are different types. If we could porta=
bly alias unique_ptr<T>* to T**, then I could take advantage of the a=
utomatic memory management.</div><div><br></div></div></blockquote><div><br=
></div><div>I=E2=80=99m sorry, I don=E2=80=99t get it.</div><div><br></div>=
<div>Why can=E2=80=99t you return a view of inputs if stages is empty and r=
eturn a view of stages.back() otherwise?</div></div><br><div>Bye,</div><div=
>Nicola</div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
--Apple-Mail=_A7F1EF88-4131-45DC-BD1A-FBB1FB1DA128--
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Fri, 16 Jan 2015 09:58:01 -0800 (PST)
Raw View
------=_Part_1127_49078328.1421431081119
Content-Type: multipart/alternative;
boundary="----=_Part_1128_225738248.1421431081119"
------=_Part_1128_225738248.1421431081119
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Friday, January 16, 2015 at 10:30:50 AM UTC-5, David Rodr=C3=ADguez Ibea=
s=20
wrote:
>
> Not ideal, but you could have an additional member:
>
> vector<T*> current;
>
> And have it initialized with 'inputs' and updated with the current view o=
f=20
> the data whenever a stage completes... If you don't need to go back to th=
e=20
> inputs after the first stage completes, you could reuse the 'inputs' memb=
er.
>
=20
Allocating another vector and wasting more space and paying for additional=
=20
memory allocations just to work around a quirk of the language is a=20
tradeoff I'm rarely willing to make.=20
>
> Regarding the aliasing of 'unique_ptr<T>*' with 'T**' (or even 'T *const=
=20
> *'), the problem is that this makes sense only for specializations of=20
> 'std::unique_ptr<T,D>' with stateless deleters, and would probably be=20
> confusing (why is it sometimes "convertible", sometimes not) or dangerous=
=20
> (reinterpreting the deleter as a 'T*').
>
=20
Using something new like alias_cast<T>() could catch these issues (casting=
=20
a unique_ptr* with a stateful deleter to T*) at compile time. I do not=20
think it would be a good idea to just create one weird exception for=20
reinterpret_cast<> and leave it to users to discover misuse at runtime.
=20
=20
> On Friday, January 16, 2015 at 12:46:57 PM UTC-5, Nicola Gigante wrote:
>
=20
> I=E2=80=99m sorry, I don=E2=80=99t get it.
>
> Why can=E2=80=99t you return a view of inputs if stages is empty and retu=
rn a view=20
> of stages.back() otherwise?
> =20
>
=20
I can if I manage the memory myself and use std::vector<T*> for both inputs=
=20
and stages. If I want to use std::vector<std::unique_ptr<T>> for the stages=
=20
I'm screwed because then stages and inputs are different type and I cannot=
=20
create a view which may reference either one.
=20
Adding a single new / delete pair to any class adds a lot of necessary=20
boilerplate code (the big 5), potential for memory bugs, and careful=20
exception safety concerns in implementation. I really don't like writing=20
new and delete anymore.
=20
=20
--=20
---=20
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 e=
mail 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-proposa=
ls/.
------=_Part_1128_225738248.1421431081119
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div><br>On Friday, January 16, 2015 at 10:30:50 AM UTC-5,=
David Rodr=C3=ADguez Ibeas wrote:<blockquote style=3D"margin: 0px 0px 0px =
0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-lef=
t-width: 1px; border-left-style: solid;" class=3D"gmail_quote"><div dir=3D"=
ltr">Not ideal, but you could have an additional member:<br><br>vector<T=
*> current;<br><br>And have it initialized with 'inputs' and updated wit=
h the current view of the data whenever a stage completes... If you don't n=
eed to go back to the inputs after the first stage completes, you could reu=
se the 'inputs' member.<br></div></blockquote><div> </div><div>Allocat=
ing another vector and wasting more space and paying for additional me=
mory allocations just to work around a quirk of the language is a trad=
eoff I'm rarely willing to make. </div><blockquote style=3D"margin: 0p=
x 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); =
border-left-width: 1px; border-left-style: solid;" class=3D"gmail_quote"><d=
iv dir=3D"ltr"><br>Regarding the aliasing of 'unique_ptr<T>*' with 'T=
**' (or even 'T *const *'), the problem is that this makes sense only for s=
pecializations of 'std::unique_ptr<T,D>' with stateless deleters, and=
would probably be confusing (why is it sometimes "convertible", sometimes =
not) or dangerous (reinterpreting the deleter as a 'T*').<br></div></blockq=
uote><div> </div><div>Using something new like alias_cast<T>=
;() could catch these issues (casting a unique_ptr* with a stateful deleter=
to T*) at compile time. I do not think it would be a good i=
dea to just create one weird exception for reinterpret_cast<> an=
d leave it to users to discover misuse at runtime.</div><div> </div><d=
iv> </div><blockquote style=3D"margin: 0px 0px 0px 0.8ex; padding-left=
: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px; borde=
r-left-style: solid;" class=3D"gmail_quote"><div dir=3D"ltr">On Friday, Jan=
uary 16, 2015 at 12:46:57 PM UTC-5, Nicola Gigante wrote:</div></blockquote=
></div><blockquote style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; b=
order-left-color: rgb(204, 204, 204); border-left-width: 1px; border-left-s=
tyle: solid;" class=3D"gmail_quote"><div style=3D"word-wrap: break-word;"><=
div><div> </div><div>I=E2=80=99m sorry, I don=E2=80=99t get it.</div><=
div><br></div><div>Why can=E2=80=99t you return a view of inputs if stages =
is empty and return a view of stages.back() otherwise?</div></div><div>&nbs=
p;</div></div></blockquote><div> </div><div>I can if I manage the memo=
ry myself and use std::vector<T*> for both inputs and stages. If I&nb=
sp;want to use std::vector<std::unique_ptr<T>> for the sta=
ges I'm screwed because then stages and inputs are different type and I can=
not create a view which may reference either one.</div><div> </div><di=
v>Adding a single new / delete pair to any class adds a lot of necessary bo=
ilerplate code (the big 5), potential for memory bugs, and careful exc=
eption safety concerns in implementation. I really don't like writing new a=
nd delete anymore.</div><div> </div><div> </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" 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_1128_225738248.1421431081119--
------=_Part_1127_49078328.1421431081119--
.
Author: inkwizytoryankes@gmail.com
Date: Fri, 16 Jan 2015 11:06:49 -0800 (PST)
Raw View
------=_Part_750_397583802.1421435209953
Content-Type: multipart/alternative;
boundary="----=_Part_751_1369334397.1421435209953"
------=_Part_751_1369334397.1421435209953
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
One solution is use unique pointer with custom deleter for both vector.=20
Foreign pointer would have dummy destructor.=20
If you create custom class for that deleter, overhead would be 1 byte if=20
you are lucky.
Another is replace vector with something that own pointers in it and can=20
return array of them.
On Friday, January 16, 2015 at 6:58:01 PM UTC+1, Matthew Fioravante wrote:
>
>
> On Friday, January 16, 2015 at 10:30:50 AM UTC-5, David Rodr=C3=ADguez Ib=
eas=20
> wrote:
>>
>> Not ideal, but you could have an additional member:
>>
>> vector<T*> current;
>>
>> And have it initialized with 'inputs' and updated with the current view=
=20
>> of the data whenever a stage completes... If you don't need to go back t=
o=20
>> the inputs after the first stage completes, you could reuse the 'inputs'=
=20
>> member.
>>
> =20
> Allocating another vector and wasting more space and paying for additiona=
l=20
> memory allocations just to work around a quirk of the language is a=20
> tradeoff I'm rarely willing to make.=20
>
>>
>> Regarding the aliasing of 'unique_ptr<T>*' with 'T**' (or even 'T *const=
=20
>> *'), the problem is that this makes sense only for specializations of=20
>> 'std::unique_ptr<T,D>' with stateless deleters, and would probably be=20
>> confusing (why is it sometimes "convertible", sometimes not) or dangerou=
s=20
>> (reinterpreting the deleter as a 'T*').
>>
> =20
> Using something new like alias_cast<T>() could catch these issues (castin=
g=20
> a unique_ptr* with a stateful deleter to T*) at compile time. I do not=20
> think it would be a good idea to just create one weird exception for=20
> reinterpret_cast<> and leave it to users to discover misuse at runtime.
> =20
> =20
>
>> On Friday, January 16, 2015 at 12:46:57 PM UTC-5, Nicola Gigante wrote:
>>
> =20
>> I=E2=80=99m sorry, I don=E2=80=99t get it.
>>
>> Why can=E2=80=99t you return a view of inputs if stages is empty and ret=
urn a=20
>> view of stages.back() otherwise?
>> =20
>>
> =20
> I can if I manage the memory myself and use std::vector<T*> for both=20
> inputs and stages. If I want to use std::vector<std::unique_ptr<T>> for t=
he=20
> stages I'm screwed because then stages and inputs are different type and =
I=20
> cannot create a view which may reference either one.
> =20
> Adding a single new / delete pair to any class adds a lot of necessary=20
> boilerplate code (the big 5), potential for memory bugs, and careful=20
> exception safety concerns in implementation. I really don't like writing=
=20
> new and delete anymore.
> =20
> =20
>
--=20
---=20
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 e=
mail 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-proposa=
ls/.
------=_Part_751_1369334397.1421435209953
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">One solution is use unique pointer with custom deleter for=
both vector. Foreign pointer would have dummy destructor. <br>If you creat=
e custom class for that deleter, overhead would be 1 byte if you are lucky.=
<br><br>Another is replace vector with something that own pointers in it an=
d can return array of them.<br><br>On Friday, January 16, 2015 at 6:58:01 P=
M UTC+1, Matthew Fioravante wrote:<blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><div><br>On Friday, January 16, 2015 at 10:30:50 AM =
UTC-5, David Rodr=C3=ADguez Ibeas wrote:<blockquote style=3D"margin:0px 0px=
0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-=
width:1px;border-left-style:solid" class=3D"gmail_quote"><div dir=3D"ltr">N=
ot ideal, but you could have an additional member:<br><br>vector<T*> =
current;<br><br>And have it initialized with 'inputs' and updated with the =
current view of the data whenever a stage completes... If you don't need to=
go back to the inputs after the first stage completes, you could reuse the=
'inputs' member.<br></div></blockquote><div> </div><div>Allocating an=
other vector and wasting more space and paying for additional memory a=
llocations just to work around a quirk of the language is a tradeoff I=
'm rarely willing to make. </div><blockquote style=3D"margin:0px 0px 0=
px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-wi=
dth:1px;border-left-style:solid" class=3D"gmail_quote"><div dir=3D"ltr"><br=
>Regarding the aliasing of 'unique_ptr<T>*' with 'T**' (or even 'T *c=
onst *'), the problem is that this makes sense only for specializations of =
'std::unique_ptr<T,D>' with stateless deleters, and would probably be=
confusing (why is it sometimes "convertible", sometimes not) or dangerous =
(reinterpreting the deleter as a 'T*').<br></div></blockquote><div> </=
div><div>Using something new like alias_cast<T>() could catch th=
ese issues (casting a unique_ptr* with a stateful deleter to T*) at co=
mpile time. I do not think it would be a good idea to just c=
reate one weird exception for reinterpret_cast<> and leave it to user=
s to discover misuse at runtime.</div><div> </div><div> </div><bl=
ockquote style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-col=
or:rgb(204,204,204);border-left-width:1px;border-left-style:solid" class=3D=
"gmail_quote"><div dir=3D"ltr">On Friday, January 16, 2015 at 12:46:57 PM U=
TC-5, Nicola Gigante wrote:</div></blockquote></div><blockquote style=3D"ma=
rgin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);=
border-left-width:1px;border-left-style:solid" class=3D"gmail_quote"><div s=
tyle=3D"word-wrap:break-word"><div><div> </div><div>I=E2=80=99m sorry,=
I don=E2=80=99t get it.</div><div><br></div><div>Why can=E2=80=99t you ret=
urn a view of inputs if stages is empty and return a view of stages.back() =
otherwise?</div></div><div> </div></div></blockquote><div> </div>=
<div>I can if I manage the memory myself and use std::vector<T*> for =
both inputs and stages. If I want to use std::vector<std::uniq=
ue_ptr<T><wbr>> for the stages I'm screwed because then stages and=
inputs are different type and I cannot create a view which may reference e=
ither one.</div><div> </div><div>Adding a single new / delete pair to =
any class adds a lot of necessary boilerplate code (the big 5), potent=
ial for memory bugs, and careful exception safety concerns in implementatio=
n. I really don't like writing new and delete anymore.</div><div> </di=
v><div> </div></div></blockquote></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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_751_1369334397.1421435209953--
------=_Part_750_397583802.1421435209953--
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Fri, 16 Jan 2015 11:36:11 -0800 (PST)
Raw View
------=_Part_1098_1377898294.1421436971856
Content-Type: multipart/alternative;
boundary="----=_Part_1099_115742072.1421436971856"
------=_Part_1099_115742072.1421436971856
Content-Type: text/plain; charset=UTF-8
On Friday, January 16, 2015 at 2:11:31 PM UTC-5, Nevin ":-)" Liber wrote:
>
>
> Given that you said this is a big use case already, how are you dealing
> with copying FooSlow objects?
>
I'm not. I've opted to manage the memory manually in my code by just using
2 vector<T*>.
>
> If you really want to do something like this, why can't you just use
> vector<shared_ptr<T>>? You at least get the pointer syntax with any range
> you return.
>
Using shared_ptr<> would indeed solve my current problem but that change
has much farther rearching consequences. Adding shared_ptr<T> all over the
place is not usually a good solution unless your system is designed shared
ownership semantics. Shared ownership has performance overhead and it also
makes it very hard to reason about when resources are actually cleaned up.
>
>
>> Another alternative would be to have some guarantee in the standard
>> that reinterpret_cast<T*>(std::unique_ptr<T>()) is valid.
>>
>
> Seems extremely unlikely C++ will move in this direction.
>
Thats not surprising, such a feature seems low level, dangerous, and only
useful in some narrow cases. Still it would be nice to have. Even though
its ugly, it would allow me in this case to design a nice interface with
the ugly cast buried in the private implementation details.
I'd be interested to know if such a thing could be used within a greater
scope for optimizing a ranges library.
> I don't see why this case is different than any other case where you have
> a vector<A> and want to return a range<B>. I don't see that the
> unique_ptr<T> -> T* case is all that special (or even common).
>
The general problem is as you said vector<A> -> range<B>. Actually my case
its even worse because I'm trying to do construct a range<B> sometimes from
vector<A> and sometimes from vector<B>, so the hypothetical range type
needs to keep track of how it was constructed and do the adaptation as
needed.
This is generally not possible unless your range object contains a lot of
additional logic and references for transparently adapting A to B. This
additional logic for doing the adaptation has some performance cost as well
as adding complexity to the code. In terms of interface design, returning
an array_view<T> is as self-explanatory as it gets. Returning some weird
templated range object not as much.
My situation is the case is when A is bitwise compatible with B and has the
same semantics. In this situation the range can just reinterpret_cast A to
B and be iterated over by the called with 0 overhead.
For my particular example unique_ptr (with default deleter) is just a raw
pointer with some extra type system magic to tell the C++ compiler to
generate code to manage the memory for you. This seems the most common use
case. The other I've seen a lot as mentioned before is in linear algebra
vectors and matrices which need to be casted to float* when its time to
send them to the graphics API.
--
---
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_1099_115742072.1421436971856
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br>On Friday, January 16, 2015 at 2:11:31 PM UTC-5, Nevin=
":-)" Liber wrote:<blockquote style=3D"margin: 0px 0px 0px 0.8ex; padding-=
left: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px; b=
order-left-style: solid;" class=3D"gmail_quote"><div dir=3D"ltr"><div><div =
class=3D"gmail_quote"><div> </div><div>Given that you said this is a b=
ig use case already, how are you dealing with copying FooSlow objects?<br><=
/div></div></div></div></blockquote><div> </div><div>I'm not. I'v=
e opted to manage the memory manually in my code by just using 2 vecto=
r<T*>.</div><div> </div><blockquote style=3D"margin: 0px 0px 0px=
0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-le=
ft-width: 1px; border-left-style: solid;" class=3D"gmail_quote"><div dir=3D=
"ltr"><div><div class=3D"gmail_quote"><div> </div><div>If you really w=
ant to do something like this, why can't you just use vector<shared_ptr&=
lt;T>>? You at least get the pointer syntax with any range you =
return.</div></div></div></div></blockquote><div> </div><div>Using sha=
red_ptr<> would indeed solve my current problem but that change has m=
uch farther rearching consequences. Adding shared_ptr<T> all over the=
place is not usually a good solution unless your system is designed shared=
ownership semantics. Shared ownership has performance overhead and it also=
makes it very hard to reason about when resources are actually cleaned up.=
</div><div> </div><blockquote style=3D"margin: 0px 0px 0px 0.8ex; pad=
ding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1=
px; border-left-style: solid;" class=3D"gmail_quote"><div dir=3D"ltr"><div>=
<div class=3D"gmail_quote"><div></div><div> </div><blockquote style=3D=
"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, =
204, 204); border-left-width: 1px; border-left-style: solid;" class=3D"gmai=
l_quote"><div dir=3D"ltr"><div> Another alternative would be to have =
some guarantee in the standard that reinterpret_cast<T*>(std::<wbr>un=
ique_ptr<T>()) is valid.</div></div></blockquote><div><br></div><div>=
Seems extremely unlikely C++ will move in this direction.<br></div></div></=
div></div></blockquote><div> </div><div>Thats not surprising, such a f=
eature seems low level, dangerous, and only useful in some narrow cases. St=
ill it would be nice to have. Even though its ugly, it would allow me in th=
is case to design a nice interface with the ugly cast buried in the private=
implementation details.</div><div> </div><div>I'd be interested to kn=
ow if such a thing could be used within a greater scope for optimizing a ra=
nges library.</div><div> </div><blockquote style=3D"margin: 0px 0px 0p=
x 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-l=
eft-width: 1px; border-left-style: solid;" class=3D"gmail_quote"><div dir=
=3D"ltr"><div><div class=3D"gmail_quote"><div></div><div>I don't see why th=
is case is different than any other case where you have a vector<A> a=
nd want to return a range<B>. I don't see that the unique_ptr&l=
t;T> -> T* case is all that special (or even common).</div></div></di=
v></div></blockquote><div> </div><div>The general problem is as you sa=
id vector<A> -> range<B>. Actually my case its even worse be=
cause I'm trying to do construct a range<B> sometimes from vector<=
A> and sometimes from vector<B>, so the hypothetical range type ne=
eds to keep track of how it was constructed and do the adaptation as needed=
.. </div><div> </div><div>This is generally not possible unless your ra=
nge object contains a lot of additional logic and references for transparen=
tly adapting A to B. This additional logic for doing the adaptation has som=
e performance cost as well as adding complexity to the code. In terms of in=
terface design, returning an array_view<T> is as self-explanatory as =
it gets. Returning some weird templated range object not as much.</div><div=
> </div><div>My situation is the case is when A is bitw=
ise compatible with B and has the same semantics. In this situation the ran=
ge can just reinterpret_cast A to B and be iterated over by the called with=
0 overhead.</div><div> </div><div>For my particular example unique_pt=
r (with default deleter) is just a raw pointer with some extra type system =
magic to tell the C++ compiler to generate code to manage the memory for yo=
u. This seems the most common use case. The other I've seen a lot as mentio=
ned before is in linear algebra vectors and matrices which need to be caste=
d to float* when its time to send them to the graphics API.</div><div> =
;</div><div> </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" 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_1099_115742072.1421436971856--
------=_Part_1098_1377898294.1421436971856--
.
Author: Nevin Liber <nevin@eviloverlord.com>
Date: Fri, 16 Jan 2015 13:54:04 -0600
Raw View
--001a113a0bbc19f4c9050cca5879
Content-Type: text/plain; charset=UTF-8
On 16 January 2015 at 13:36, Matthew Fioravante <fmatthew5876@gmail.com>
wrote:
>
>
>> Another alternative would be to have some guarantee in the standard
>> that reinterpret_cast<T*>(std::unique_ptr<T>()) is valid.
>>
>
> Seems extremely unlikely C++ will move in this direction.
> Thats not surprising, such a feature seems low level, dangerous, and only
> useful in some narrow cases. Still it would be nice to have.
>
Would it? This provides a hole in encapsulation as big as a truck.
Do you really want to allow people to legally write
*reinterpret_cast<T**>(p) = nullptr;
instead of p.release()? Or worse,
*reinterpret_cast<T**>(p) = q;
thus bypassing all of unique_ptr's invariants.
> Even though its ugly, it would allow me in this case to design a nice
> interface with the ugly cast buried in the private implementation details.
>
So you want your classes to have private implementation details but you
don't want the standard library classes to have private implementation
details. Really?
The general problem is as you said vector<A> -> range<B>. Actually my case
> its even worse because I'm trying to do construct a range<B> sometimes from
> vector<A> and sometimes from vector<B>, so the hypothetical range type
> needs to keep track of how it was constructed and do the adaptation as
> needed.
>
> This is generally not possible unless your range object contains a lot of
> additional logic and references for transparently adapting A to B. This
> additional logic for doing the adaptation has some performance cost as well
> as adding complexity to the code. In terms of interface design, returning
> an array_view<T> is as self-explanatory as it gets. Returning some weird
> templated range object not as much.
>
> My situation is the case is when A is bitwise compatible with B and has
> the same semantics. In this situation the range can just reinterpret_cast A
> to B and be iterated over by the called with 0 overhead.
>
> For my particular example unique_ptr (with default deleter) is just a raw
> pointer with some extra type system magic to tell the C++ compiler to
> generate code to manage the memory for you.
>
A. Nothing in the standard requires that implementation.
B. Classes maintain invariants. You shouldn't be able to legally get
around that just by performing a cast, or you'll never be able to reason
about the resulting mess.
--
Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> (847) 691-1404
--
---
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/.
--001a113a0bbc19f4c9050cca5879
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On 16 January 2015 at 13:36, Matthew Fioravante <span dir=
=3D"ltr"><<a href=3D"mailto:fmatthew5876@gmail.com" target=3D"_blank">fm=
atthew5876@gmail.com</a>></span> wrote:<br><div class=3D"gmail_extra"><d=
iv class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:=
0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><s=
pan class=3D""></span><span class=3D""><div>=C2=A0</div></span><div dir=3D"=
ltr"><div><div class=3D"gmail_quote"><blockquote style=3D"margin:0px 0px 0p=
x 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-wid=
th:1px;border-left-style:solid" class=3D"gmail_quote"><div dir=3D"ltr"><div=
>=C2=A0 Another alternative would be to have some guarantee in the standard=
that reinterpret_cast<T*>(std::unique_ptr<T>()) is valid.</div=
></div></blockquote><div><br></div><div>Seems extremely unlikely C++ will m=
ove in this direction.<br></div></div></div></div><div>Thats not surprising=
, such a feature seems low level, dangerous, and only useful in some narrow=
cases. Still it would be nice to have.</div></div></blockquote><div><br></=
div><div>Would it?=C2=A0 This provides a hole in encapsulation as big as a =
truck.<br><br></div><div>Do you really want to allow people to legally writ=
e<br><br>*reinterpret_cast<T**>(p) =3D nullptr;<br></div><div><br></d=
iv><div>instead of p.release()?=C2=A0 Or worse,<br><br></div><div>*reinterp=
ret_cast<T**>(p)=C2=A0 =3D q;<br><br></div><div>thus bypassing all of=
unique_ptr's invariants.<br></div><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div> Even though its ugly, it would allow m=
e in this case to design a nice interface with the ugly cast buried in the =
private implementation details.</div></div></blockquote><div><br></div><div=
>So you want your classes to have private implementation details but you do=
n't want the standard library classes to have private implementation de=
tails.=C2=A0 Really?<br><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><span class=3D""></span><div>The general problem is as you said ve=
ctor<A> -> range<B>. Actually my case its even worse because=
I'm trying to do construct a range<B> sometimes from vector<A=
> and sometimes from vector<B>, so the hypothetical range type nee=
ds to keep track of how it was constructed and do the adaptation as needed.=
</div><div>=C2=A0</div><div>This is generally not possible unless your ran=
ge object contains a lot of additional logic and references for transparent=
ly adapting A to B. This additional logic for doing the adaptation has some=
performance cost as well as adding complexity to the code. In terms of int=
erface design, returning an array_view<T> is as self-explanatory as i=
t gets. Returning some weird templated range object not as much.</div><div>=
=C2=A0</div><div>My=C2=A0situation=C2=A0is the case is when=C2=A0A is bitwi=
se compatible with B and has the same semantics. In this situation the rang=
e can just reinterpret_cast A to B and be iterated over by the called with =
0 overhead.</div><div>=C2=A0</div><div>For my particular example unique_ptr=
(with default deleter) is just a raw pointer with some extra type system m=
agic to tell the C++ compiler to generate code to manage the memory for you=
..</div></div></blockquote><div><br></div><div>A.=C2=A0 Nothing in the stand=
ard requires that implementation.<br><br></div><div>B.=C2=A0 Classes mainta=
in invariants.=C2=A0 You shouldn't be able to legally get around that j=
ust by performing a cast, or you'll never be able to reason about the r=
esulting mess.<br clear=3D"all"></div></div>-- <br><div class=3D"gmail_sign=
ature">=C2=A0Nevin ":-)" Liber=C2=A0 <mailto:<a href=3D"mailto=
:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a>>=
=C2=A0 (847) 691-1404</div>
</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" 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 />
--001a113a0bbc19f4c9050cca5879--
.
Author: Greg Marr <gregmmarr@gmail.com>
Date: Fri, 16 Jan 2015 11:59:08 -0800 (PST)
Raw View
------=_Part_78_1679219764.1421438348600
Content-Type: multipart/alternative;
boundary="----=_Part_79_416484674.1421438348601"
------=_Part_79_416484674.1421438348601
Content-Type: text/plain; charset=UTF-8
On Friday, January 16, 2015 at 2:36:11 PM UTC-5, Matthew Fioravante wrote:
>
> My situation is the case is when A is bitwise compatible with B and has
> the same semantics. In this situation the range can just reinterpret_cast A
> to B and be iterated over by the called with 0 overhead.
>
Ah, but there's the problem. Even though A may be bitwise compatible with
B, it does not have the same semantics. There is a major difference when
it comes to assignment.
With std::vector<T *>, assigning to an element just changes the pointer.
With std::vector<std::unique_ptr<T>>, assigning to an element deletes an
object. Therefore, the two types are not compatible.
--
---
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_79_416484674.1421438348601
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, January 16, 2015 at 2:36:11 PM UTC-5, Matthew F=
ioravante wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r"><div>My situation is the case is when A is bitwise compat=
ible with B and has the same semantics. In this situation the range can jus=
t reinterpret_cast A to B and be iterated over by the called with 0 overhea=
d.</div></div></blockquote><div><br></div><div>Ah, but there's the problem.=
Even though A may be bitwise compatible with B, it does not have the=
same semantics. There is a major difference when it comes to assignm=
ent.</div><div><br></div><div>With std::vector<T *>, assigning to an =
element just changes the pointer. With std::vector<std::unique_ptr=
<T>>, assigning to an element deletes an object. Therefore, =
the two types are not compatible.</div><div><br></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" 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_79_416484674.1421438348601--
------=_Part_78_1679219764.1421438348600--
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Fri, 16 Jan 2015 12:21:22 -0800 (PST)
Raw View
------=_Part_1232_1542209782.1421439682200
Content-Type: multipart/alternative;
boundary="----=_Part_1233_1939670431.1421439682201"
------=_Part_1233_1939670431.1421439682201
Content-Type: text/plain; charset=UTF-8
On Friday, January 16, 2015 at 2:54:46 PM UTC-5, Nevin ":-)" Liber wrote:
> Would it? This provides a hole in encapsulation as big as a truck.
>
> Do you really want to allow people to legally write
>
> *reinterpret_cast<T**>(p) = nullptr;
>
> instead of p.release()? Or worse,
>
> *reinterpret_cast<T**>(p) = q;
>
> thus bypassing all of unique_ptr's invariants.
>
This is a very good point, I forgot to add in const. I didn't show it my
example here but I'm actually returning a carray_view<T*> (i.e
array_view<T* const>).
In this case we can only view the pointer but not modify it. We can of
course do non-const operations on the pointed to objects, but thats the
same for a const unique_ptr. We can't do anything here that would violate
unique_ptr's invariants.
For the case of the Vec4, aliasing to non-const float* may be fine as well
as long as the Vec4 type doesn't maintain any invariants over its elements
(basically a POD style struct).
>
>
>> Even though its ugly, it would allow me in this case to design a nice
>> interface with the ugly cast buried in the private implementation details.
>>
>
> So you want your classes to have private implementation details but you
> don't want the standard library classes to have private implementation
> details. Really?
>
Adding a specification that std::unique_ptr<T> can alias to T* const makes
that detail a part of its interface and as a consequence places
restrictions on the private implementation.
>
> The general problem is as you said vector<A> -> range<B>. Actually my case
>> its even worse because I'm trying to do construct a range<B> sometimes from
>> vector<A> and sometimes from vector<B>, so the hypothetical range type
>> needs to keep track of how it was constructed and do the adaptation as
>> needed.
>>
>> This is generally not possible unless your range object contains a lot of
>> additional logic and references for transparently adapting A to B. This
>> additional logic for doing the adaptation has some performance cost as well
>> as adding complexity to the code. In terms of interface design, returning
>> an array_view<T> is as self-explanatory as it gets. Returning some weird
>> templated range object not as much.
>>
>> My situation is the case is when A is bitwise compatible with B and has
>> the same semantics. In this situation the range can just reinterpret_cast A
>> to B and be iterated over by the called with 0 overhead.
>>
>> For my particular example unique_ptr (with default deleter) is just a raw
>> pointer with some extra type system magic to tell the C++ compiler to
>> generate code to manage the memory for you.
>>
>
> A. Nothing in the standard requires that implementation.
>
It's the most reasonable implementation of unique_ptr. The whole idea of
this thread is discussing whether or not some feature to specify that
restriction and sub-sequently adding to unique_ptr would make sense to do.
>
> B. Classes maintain invariants. You shouldn't be able to legally get
> around that just by performing a cast, or you'll never be able to reason
> about the resulting mess.
>
I agree, and if used correctly via const the invariants can be maintained.
--
---
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_1233_1939670431.1421439682201
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br>On Friday, January 16, 2015 at 2:54:46 PM UTC-5, Nevin=
":-)" Liber wrote:<br><blockquote style=3D"margin: 0px 0px 0px 0.8ex; padd=
ing-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1p=
x; border-left-style: solid;" class=3D"gmail_quote"><div dir=3D"ltr"><div><=
div class=3D"gmail_quote"><div>Would it? This provides a hole in enca=
psulation as big as a truck.<br><br></div><div>Do you really want to allow =
people to legally write<br><br>*reinterpret_cast<T**>(p) =3D nullptr;=
<br></div><div><br></div><div>instead of p.release()? Or worse,<br><b=
r></div><div>*reinterpret_cast<T**>(p) =3D q;<br><br></div><div=
>thus bypassing all of unique_ptr's invariants.<br></div></div></div></div>=
</blockquote><div>This is a very good point, I forgot to add in const. I di=
dn't show it my example here but I'm actually returning a carray_view<T*=
> (i.e array_view<T* const>).</div><div> </div><div>In this c=
ase we can only view the pointer but not modify it. We can of course do non=
-const operations on the pointed to objects, but thats the same for a const=
unique_ptr. We can't do anything here that would violate unique_ptr's inva=
riants.</div><div> </div><div>For the case of the Vec4, aliasing to no=
n-const float* may be fine as well as long as the Vec4 type doesn't maintai=
n any invariants over its elements (basically a POD style struct).</div><di=
v> </div><blockquote style=3D"margin: 0px 0px 0px 0.8ex; padding-left:=
1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px; border=
-left-style: solid;" class=3D"gmail_quote"><div dir=3D"ltr"><div><div class=
=3D"gmail_quote"><div></div><div> </div><blockquote style=3D"margin: 0=
px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204);=
border-left-width: 1px; border-left-style: solid;" class=3D"gmail_quote"><=
div dir=3D"ltr"><div> Even though its ugly, it would allow me in this case =
to design a nice interface with the ugly cast buried in the private impleme=
ntation details.</div></div></blockquote><div><br></div><div>So you want yo=
ur classes to have private implementation details but you don't want the st=
andard library classes to have private implementation details. Really=
?<br></div></div></div></div></blockquote><div> </div><div>Adding a sp=
ecification that std::unique_ptr<T> can alias to T* const makes =
that detail a part of its interface and as a consequence places restriction=
s on the private implementation. </div><div> </div><blockquote style=
=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(20=
4, 204, 204); border-left-width: 1px; border-left-style: solid;" class=3D"g=
mail_quote"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div><br></div=
><blockquote style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-=
left-color: rgb(204, 204, 204); border-left-width: 1px; border-left-style: =
solid;" class=3D"gmail_quote"><div dir=3D"ltr"><span></span><div>The genera=
l problem is as you said vector<A> -> range<B>. Actually my =
case its even worse because I'm trying to do construct a range<B> som=
etimes from vector<A> and sometimes from vector<B>, so the hypo=
thetical range type needs to keep track of how it was constructed and do th=
e adaptation as needed. </div><div> </div><div>This is generally not p=
ossible unless your range object contains a lot of additional logic and ref=
erences for transparently adapting A to B. This additional logic for doing =
the adaptation has some performance cost as well as adding complexity to th=
e code. In terms of interface design, returning an array_view<T> is a=
s self-explanatory as it gets. Returning some weird templated range object =
not as much.</div><div> </div><div>My situation is the case =
is when A is bitwise compatible with B and has the same semantics. In =
this situation the range can just reinterpret_cast A to B and be iterated o=
ver by the called with 0 overhead.</div><div> </div><div>For my partic=
ular example unique_ptr (with default deleter) is just a raw pointer with s=
ome extra type system magic to tell the C++ compiler to generate code to ma=
nage the memory for you.</div></div></blockquote><div><br></div><div>A.&nbs=
p; Nothing in the standard requires that implementation.</div></div></div><=
/div></blockquote><div> </div><div>It's the most reasonable implementa=
tion of unique_ptr. The whole idea of this thread is discussing whether or =
not some feature to specify that restriction and sub-sequently adding to un=
ique_ptr would make sense to do.</div><div> </div><blockquote style=3D=
"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, =
204, 204); border-left-width: 1px; border-left-style: solid;" class=3D"gmai=
l_quote"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div><br></div><d=
iv>B. Classes maintain invariants. You shouldn't be able to leg=
ally get around that just by performing a cast, or you'll never be able to =
reason about the resulting mess.</div></div></div></div></blockquote><div>&=
nbsp;</div><div>I agree, and if used correctly via const the invariant=
s can be maintained.</div><div> </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" 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_1233_1939670431.1421439682201--
------=_Part_1232_1542209782.1421439682200--
.
Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Sat, 17 Jan 2015 08:01:23 +0000
Raw View
Of course, you could always use a union (I can't believe I just said that :) )
On 1/16/15, Matthew Fioravante <fmatthew5876@gmail.com> wrote:
>
> On Friday, January 16, 2015 at 2:54:46 PM UTC-5, Nevin ":-)" Liber wrote:
>
>> Would it? This provides a hole in encapsulation as big as a truck.
>>
>> Do you really want to allow people to legally write
>>
>> *reinterpret_cast<T**>(p) = nullptr;
>>
>> instead of p.release()? Or worse,
>>
>> *reinterpret_cast<T**>(p) = q;
>>
>> thus bypassing all of unique_ptr's invariants.
>>
> This is a very good point, I forgot to add in const. I didn't show it my
> example here but I'm actually returning a carray_view<T*> (i.e
> array_view<T* const>).
>
> In this case we can only view the pointer but not modify it. We can of
> course do non-const operations on the pointed to objects, but thats the
> same for a const unique_ptr. We can't do anything here that would violate
> unique_ptr's invariants.
>
> For the case of the Vec4, aliasing to non-const float* may be fine as well
> as long as the Vec4 type doesn't maintain any invariants over its elements
> (basically a POD style struct).
>
>
>>
>>
>>> Even though its ugly, it would allow me in this case to design a nice
>>> interface with the ugly cast buried in the private implementation
>>> details.
>>>
>>
>> So you want your classes to have private implementation details but you
>> don't want the standard library classes to have private implementation
>> details. Really?
>>
>
> Adding a specification that std::unique_ptr<T> can alias to T* const makes
> that detail a part of its interface and as a consequence places
> restrictions on the private implementation.
>
>
>>
>> The general problem is as you said vector<A> -> range<B>. Actually my case
>>
>>> its even worse because I'm trying to do construct a range<B> sometimes
>>> from
>>> vector<A> and sometimes from vector<B>, so the hypothetical range type
>>> needs to keep track of how it was constructed and do the adaptation as
>>> needed.
>>>
>>> This is generally not possible unless your range object contains a lot of
>>>
>>> additional logic and references for transparently adapting A to B. This
>>> additional logic for doing the adaptation has some performance cost as
>>> well
>>> as adding complexity to the code. In terms of interface design, returning
>>>
>>> an array_view<T> is as self-explanatory as it gets. Returning some weird
>>>
>>> templated range object not as much.
>>>
>>> My situation is the case is when A is bitwise compatible with B and has
>>> the same semantics. In this situation the range can just reinterpret_cast
>>> A
>>> to B and be iterated over by the called with 0 overhead.
>>>
>>> For my particular example unique_ptr (with default deleter) is just a raw
>>>
>>> pointer with some extra type system magic to tell the C++ compiler to
>>> generate code to manage the memory for you.
>>>
>>
>> A. Nothing in the standard requires that implementation.
>>
>
> It's the most reasonable implementation of unique_ptr. The whole idea of
> this thread is discussing whether or not some feature to specify that
> restriction and sub-sequently adding to unique_ptr would make sense to do.
>
>
>>
>> B. Classes maintain invariants. You shouldn't be able to legally get
>> around that just by performing a cast, or you'll never be able to reason
>> about the resulting mess.
>>
>
> I agree, and if used correctly via const the invariants can be maintained.
>
>
> --
>
> ---
> 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/.
>
--
---
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/.
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Mon, 23 Feb 2015 15:52:17 -0800 (PST)
Raw View
------=_Part_1963_1986421797.1424735537088
Content-Type: multipart/alternative;
boundary="----=_Part_1964_1010365917.1424735537089"
------=_Part_1964_1010365917.1424735537089
Content-Type: text/plain; charset=UTF-8
Sorry to beat a probably dead horse, but I really keep running into this
problem over and over again. Even if you aren't using array_view, its still
a problem.
class Foo {
public:
const auto& getA() { return a; }
const auto& getB() { return b; }
private:
vector<std::unique_ptr<T>> a;
vector<T*> b;
}:
In order to avoid a copy, we're forced to leak the implementation details
that A is managed by unique_ptr but B is not. Even if we decide making a
copy is ok, this still means that getA() has to return by value while
getB() can continue to return by const reference. The ideal scenario which
is just returning array_view<T*> is impossible because there is nowhere to
store the copy of a.
Both a and b are just vectors of pointers. The fact that a has additional
logic tacked on to automatically manage memory is irrelevant to the client
of Foo.
This issue is making unique_ptr very cumbersome to use. Ideally I'd like to
just be able to specify memory management once within the containing class
data members and then pass around array_view<T*> everywhere externally,
clients not knowing, caring, or recompiling whether the view points to a
set of managed or unmanaged pointers.
On Saturday, January 17, 2015 at 3:01:24 AM UTC-5, Douglas Boffey wrote:
>
> Of course, you could always use a union (I can't believe I just said that
> :) )
>
> On 1/16/15, Matthew Fioravante <fmatth...@gmail.com <javascript:>> wrote:
> >
> > On Friday, January 16, 2015 at 2:54:46 PM UTC-5, Nevin ":-)" Liber
> wrote:
> >
> >> Would it? This provides a hole in encapsulation as big as a truck.
> >>
> >> Do you really want to allow people to legally write
> >>
> >> *reinterpret_cast<T**>(p) = nullptr;
> >>
> >> instead of p.release()? Or worse,
> >>
> >> *reinterpret_cast<T**>(p) = q;
> >>
> >> thus bypassing all of unique_ptr's invariants.
> >>
> > This is a very good point, I forgot to add in const. I didn't show it my
> > example here but I'm actually returning a carray_view<T*> (i.e
> > array_view<T* const>).
> >
> > In this case we can only view the pointer but not modify it. We can of
> > course do non-const operations on the pointed to objects, but thats the
> > same for a const unique_ptr. We can't do anything here that would
> violate
> > unique_ptr's invariants.
> >
> > For the case of the Vec4, aliasing to non-const float* may be fine as
> well
> > as long as the Vec4 type doesn't maintain any invariants over its
> elements
> > (basically a POD style struct).
> >
> >
> >>
> >>
> >>> Even though its ugly, it would allow me in this case to design a nice
> >>> interface with the ugly cast buried in the private implementation
> >>> details.
> >>>
> >>
> >> So you want your classes to have private implementation details but you
> >> don't want the standard library classes to have private implementation
> >> details. Really?
> >>
> >
> > Adding a specification that std::unique_ptr<T> can alias to T* const
> makes
> > that detail a part of its interface and as a consequence places
> > restrictions on the private implementation.
> >
> >
> >>
> >> The general problem is as you said vector<A> -> range<B>. Actually my
> case
> >>
> >>> its even worse because I'm trying to do construct a range<B> sometimes
> >>> from
> >>> vector<A> and sometimes from vector<B>, so the hypothetical range type
> >>> needs to keep track of how it was constructed and do the adaptation as
> >>> needed.
> >>>
> >>> This is generally not possible unless your range object contains a lot
> of
> >>>
> >>> additional logic and references for transparently adapting A to B.
> This
> >>> additional logic for doing the adaptation has some performance cost as
> >>> well
> >>> as adding complexity to the code. In terms of interface design,
> returning
> >>>
> >>> an array_view<T> is as self-explanatory as it gets. Returning some
> weird
> >>>
> >>> templated range object not as much.
> >>>
> >>> My situation is the case is when A is bitwise compatible with B and
> has
> >>> the same semantics. In this situation the range can just
> reinterpret_cast
> >>> A
> >>> to B and be iterated over by the called with 0 overhead.
> >>>
> >>> For my particular example unique_ptr (with default deleter) is just a
> raw
> >>>
> >>> pointer with some extra type system magic to tell the C++ compiler to
> >>> generate code to manage the memory for you.
> >>>
> >>
> >> A. Nothing in the standard requires that implementation.
> >>
> >
> > It's the most reasonable implementation of unique_ptr. The whole idea of
> > this thread is discussing whether or not some feature to specify that
> > restriction and sub-sequently adding to unique_ptr would make sense to
> do.
> >
> >
> >>
> >> B. Classes maintain invariants. You shouldn't be able to legally get
> >> around that just by performing a cast, or you'll never be able to
> reason
> >> about the resulting mess.
> >>
> >
> > I agree, and if used correctly via const the invariants can be
> maintained.
> >
> >
> > --
> >
> > ---
> > 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-proposal...@isocpp.org <javascript:>.
> > To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>
> > Visit this group at
> > http://groups.google.com/a/isocpp.org/group/std-proposals/.
> >
>
--
---
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_1964_1010365917.1424735537089
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Sorry to beat a probably dead horse, but I really keep run=
ning into this problem over and over again. Even if you aren't using array_=
view, its still a problem.<br><br><div class=3D"prettyprint" style=3D"backg=
round-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-s=
tyle: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pret=
typrint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=
=3D"styled-by-prettify">class</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-=
prettify">Foo</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">public</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br> </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">auto</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> getA</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">return</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> a</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br> </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">const</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">auto</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> getB</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">return</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> b</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">private</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br> vector</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">unique_ptr</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify"><</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">T</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">>></span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> a</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br> vector</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify"><</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">*></sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> b</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">}:</span></div></code></div><br>In or=
der to avoid a copy, we're forced to leak the implementation details that A=
is managed by unique_ptr but B is not. Even if we decide making a copy is =
ok, this still means that getA() has to return by value while getB() can co=
ntinue to return by const reference. The ideal scenario which is just retur=
ning array_view<T*> is impossible because there is nowhere to store t=
he copy of a.<br><br>Both a and b are just vectors of pointers. The fact th=
at a has additional logic tacked on to automatically manage memory is irrel=
evant to the client of Foo.<br><br>This issue is making unique_ptr very cum=
bersome to use. Ideally I'd like to just be able to specify memory manageme=
nt once within the containing class data members and then pass around array=
_view<T*> everywhere externally, clients not knowing, caring, or reco=
mpiling whether the view points to a set of managed or unmanaged pointers.<=
br><br>On Saturday, January 17, 2015 at 3:01:24 AM UTC-5, Douglas Boffey wr=
ote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;">Of course, you could alway=
s use a union (I can't believe I just said that :) )
<br>
<br>On 1/16/15, Matthew Fioravante <<a href=3D"javascript:" target=3D"_b=
lank" gdf-obfuscated-mailto=3D"ILBNDxXXInkJ" rel=3D"nofollow" onmousedown=
=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'javascr=
ipt:';return true;">fmatth...@gmail.com</a>> wrote:
<br>>
<br>> On Friday, January 16, 2015 at 2:54:46 PM UTC-5, Nevin ":-)" Liber=
wrote:
<br>>
<br>>> Would it? This provides a hole in encapsulation as big a=
s a truck.
<br>>>
<br>>> Do you really want to allow people to legally write
<br>>>
<br>>> *reinterpret_cast<T**>(p) =3D nullptr;
<br>>>
<br>>> instead of p.release()? Or worse,
<br>>>
<br>>> *reinterpret_cast<T**>(p) =3D q;
<br>>>
<br>>> thus bypassing all of unique_ptr's invariants.
<br>>>
<br>> This is a very good point, I forgot to add in const. I didn't show=
it my
<br>> example here but I'm actually returning a carray_view<T*> (i=
..e
<br>> array_view<T* const>).
<br>>
<br>> In this case we can only view the pointer but not modify it. We ca=
n of
<br>> course do non-const operations on the pointed to objects, but that=
s the
<br>> same for a const unique_ptr. We can't do anything here that would =
violate
<br>> unique_ptr's invariants.
<br>>
<br>> For the case of the Vec4, aliasing to non-const float* may be fine=
as well
<br>> as long as the Vec4 type doesn't maintain any invariants over its =
elements
<br>> (basically a POD style struct).
<br>>
<br>>
<br>>>
<br>>>
<br>>>> Even though its ugly, it would allow me in this case to de=
sign a nice
<br>>>> interface with the ugly cast buried in the private impleme=
ntation
<br>>>> details.
<br>>>>
<br>>>
<br>>> So you want your classes to have private implementation detail=
s but you
<br>>> don't want the standard library classes to have private implem=
entation
<br>>> details. Really?
<br>>>
<br>>
<br>> Adding a specification that std::unique_ptr<T> can alias to =
T* const makes
<br>> that detail a part of its interface and as a consequence places
<br>> restrictions on the private implementation.
<br>>
<br>>
<br>>>
<br>>> The general problem is as you said vector<A> -> range=
<B>. Actually my case
<br>>>
<br>>>> its even worse because I'm trying to do construct a range&=
lt;B> sometimes
<br>>>> from
<br>>>> vector<A> and sometimes from vector<B>, so the=
hypothetical range type
<br>>>> needs to keep track of how it was constructed and do the a=
daptation as
<br>>>> needed.
<br>>>>
<br>>>> This is generally not possible unless your range object co=
ntains a lot of
<br>>>>
<br>>>> additional logic and references for transparently adapting=
A to B. This
<br>>>> additional logic for doing the adaptation has some perform=
ance cost as
<br>>>> well
<br>>>> as adding complexity to the code. In terms of interface de=
sign, returning
<br>>>>
<br>>>> an array_view<T> is as self-explanatory as it gets. =
Returning some weird
<br>>>>
<br>>>> templated range object not as much.
<br>>>>
<br>>>> My situation is the case is when A is bitwise compatible w=
ith B and has
<br>>>> the same semantics. In this situation the range can just r=
einterpret_cast
<br>>>> A
<br>>>> to B and be iterated over by the called with 0 overhead.
<br>>>>
<br>>>> For my particular example unique_ptr (with default deleter=
) is just a raw
<br>>>>
<br>>>> pointer with some extra type system magic to tell the C++ =
compiler to
<br>>>> generate code to manage the memory for you.
<br>>>>
<br>>>
<br>>> A. Nothing in the standard requires that implementation.
<br>>>
<br>>
<br>> It's the most reasonable implementation of unique_ptr. The whole i=
dea of
<br>> this thread is discussing whether or not some feature to specify t=
hat
<br>> restriction and sub-sequently adding to unique_ptr would make sens=
e to do.
<br>>
<br>>
<br>>>
<br>>> B. Classes maintain invariants. You shouldn't be a=
ble to legally get
<br>>> around that just by performing a cast, or you'll never be able=
to reason
<br>>> about the resulting mess.
<br>>>
<br>>
<br>> I agree, and if used correctly via const the invariants can be mai=
ntained.
<br>>
<br>>
<br>> --
<br>>
<br>> ---
<br>> You received this message because you are subscribed to the Google=
Groups
<br>> "ISO C++ Standard - Future Proposals" group.
<br>> To unsubscribe from this group and stop receiving emails from it, =
send an
<br>> email to <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-=
mailto=3D"ILBNDxXXInkJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javasc=
ript:';return true;" onclick=3D"this.href=3D'javascript:';return true;">std=
-proposal...@<wbr>isocpp.org</a>.
<br>> To post to this group, send email to <a href=3D"javascript:" targe=
t=3D"_blank" gdf-obfuscated-mailto=3D"ILBNDxXXInkJ" rel=3D"nofollow" onmous=
edown=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'ja=
vascript:';return true;">std-pr...@isocpp.org</a>.
<br>> Visit this group at
<br>> <a href=3D"http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'http://=
groups.google.com/a/isocpp.org/group/std-proposals/';return true;" onclick=
=3D"this.href=3D'http://groups.google.com/a/isocpp.org/group/std-proposals/=
';return true;">http://groups.google.com/a/<wbr>isocpp.org/group/std-<wbr>p=
roposals/</a>.
<br>>
<br></blockquote></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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_1964_1010365917.1424735537089--
------=_Part_1963_1986421797.1424735537088--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 23 Feb 2015 18:24:43 -0800 (PST)
Raw View
------=_Part_3957_5663060.1424744683718
Content-Type: multipart/alternative;
boundary="----=_Part_3958_689768952.1424744683718"
------=_Part_3958_689768952.1424744683718
Content-Type: text/plain; charset=UTF-8
On Monday, February 23, 2015 at 6:52:17 PM UTC-5, Matthew Fioravante wrote:
>
> Sorry to beat a probably dead horse, but I really keep running into this
> problem over and over again. Even if you aren't using array_view, its still
> a problem.
>
> class Foo {
> public:
> const auto& getA() { return a; }
> const auto& getB() { return b; }
> private:
> vector<std::unique_ptr<T>> a;
> vector<T*> b;
> }:
>
> In order to avoid a copy, we're forced to leak the implementation details
> that A is managed by unique_ptr but B is not. Even if we decide making a
> copy is ok, this still means that getA() has to return by value while
> getB() can continue to return by const reference. The ideal scenario which
> is just returning array_view<T*> is impossible because there is nowhere to
> store the copy of a.
>
> Both a and b are just vectors of pointers. The fact that a has additional
> logic tacked on to automatically manage memory is irrelevant to the client
> of Foo.
>
But it's very relevant to Foo. And since he's the owner and creator of the
array, he's the one who decides these things.
For all intents and purposes, your problem is the lack of modules in C++.
Here's what I mean.
What you really want to do is give people a non-modifiable view of your
stored data. Your users won't care what specific types you may wrap your
stored data in, so long as they obey certain basic principles (ie: the
expectations of a pointer to T).
The "correct" way to handle this is with templates. That is, code that
wants to consume your array_view would be a template, on the array view's
type (or the template type could be more general, a non-modifiable range of
pointer-to-T-like objects. Whatever). The problem is that now, all your
consuming code needs to live in header files. As much any code that just
passes your stuff along to others. Templates are rather viral like that.
If you had modules, you wouldn't have to care. You'd just return an
array_view<unique_ptr<T>>, and those who wanted to consume it would be a
template that takes an appropriate range. Nobody would be subjected to the
details of your memory management (unless they deliberately choose to be).
And thanks to modules, they wouldn't be subjected to the horrible
compile-times that come along with doing all this (which is the #1 reason
why people avoid doing it today. #2 is the lack of concepts).
Basically, this would be a solved problem if compile-time wasn't an issue.
This issue is making unique_ptr very cumbersome to use. Ideally I'd like to
> just be able to specify memory management once within the containing class
> data members and then pass around array_view<T*> everywhere externally,
> clients not knowing, caring, or recompiling whether the view points to a
> set of managed or unmanaged pointers.
>
Well, that's just not going to happen. std::unique_ptr does not
(necessarily) have zero overhead. It all depends on the deleter. Plus, that
would require aliasing.
The only solution here is a container that specifically handles memory
allocation, like Boost's ptr_vector. But I don't think this is a frequent
enough problem to have them standardize such a special use container.
--
---
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_3958_689768952.1424744683718
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, February 23, 2015 at 6:52:17 PM UTC-5, Matthew =
Fioravante wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr">Sorry to beat a probably dead horse, but I really keep running into thi=
s problem over and over again. Even if you aren't using array_view, its sti=
ll a problem.<br><br><div style=3D"background-color:rgb(250,250,250);border=
-color:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break=
-word"><code><div><span style=3D"color:#008">class</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#606">Foo</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"=
><br></span><span style=3D"color:#008">public</span><span style=3D"color:#6=
60">:</span><span style=3D"color:#000"><br> </span><span style=3D"col=
or:#008">const</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#008">auto</span><span style=3D"color:#660">&</span><span style=3D"co=
lor:#000"> getA</span><span style=3D"color:#660">()</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#=
000"> </span><span style=3D"color:#008">return</span><span style=3D"color:#=
000"> a</span><span style=3D"color:#660">;</span><span style=3D"color:#000"=
> </span><span style=3D"color:#660">}</span><span style=3D"color:#000"><br>=
</span><span style=3D"color:#008">const</span><span style=3D"color:#=
000"> </span><span style=3D"color:#008">auto</span><span style=3D"color:#66=
0">&</span><span style=3D"color:#000"> getB</span><span style=3D"color:=
#660">()</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">{</span><span style=3D"color:#000"> </span><span style=3D"color:#008">ret=
urn</span><span style=3D"color:#000"> b</span><span style=3D"color:#660">;<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#660">}</span=
><span style=3D"color:#000"><br></span><span style=3D"color:#008">private</=
span><span style=3D"color:#660">:</span><span style=3D"color:#000"><br>&nbs=
p; vector</span><span style=3D"color:#660"><</span><span style=3D"color:=
#000">std</span><span style=3D"color:#660">::</span><span style=3D"color:#0=
00">unique_ptr</span><span style=3D"color:#660"><</span><span style=3D"c=
olor:#000">T</span><span style=3D"color:#660">>></span><span style=3D=
"color:#000"> a</span><span style=3D"color:#660">;</span><span style=3D"col=
or:#000"><br> vector</span><span style=3D"color:#660"><</span><spa=
n style=3D"color:#000">T</span><span style=3D"color:#660">*></span><span=
style=3D"color:#000"> b</span><span style=3D"color:#660">;</span><span sty=
le=3D"color:#000"><br></span><span style=3D"color:#660">}:</span></div></co=
de></div><br>In order to avoid a copy, we're forced to leak the implementat=
ion details that A is managed by unique_ptr but B is not. Even if we decide=
making a copy is ok, this still means that getA() has to return by value w=
hile getB() can continue to return by const reference. The ideal scenario w=
hich is just returning array_view<T*> is impossible because there is =
nowhere to store the copy of a.<br><br>Both a and b are just vectors of poi=
nters. The fact that a has additional logic tacked on to automatically mana=
ge memory is irrelevant to the client of Foo.<br></div></blockquote><div><b=
r>But it's very relevant to Foo. And since he's the owner and creator of th=
e array, he's the one who decides these things.<br><br>For all intents and =
purposes, your problem is the lack of modules in C++. Here's what I mean.<b=
r><br>What you really want to do is give people a non-modifiable view of yo=
ur stored data. Your users won't care what specific types you may wrap your=
stored data in, so long as they obey certain basic principles (ie: the exp=
ectations of a pointer to T).<br><br>The "correct" way to handle this is wi=
th templates. That is, code that wants to consume your array_view would be =
a template, on the array view's type (or the template type could be more ge=
neral, a non-modifiable range of pointer-to-T-like objects. Whatever). The =
problem is that now, all your consuming code needs to live in header files.=
As much any code that just passes your stuff along to others. Templates ar=
e rather viral like that.<br><br>If you had modules, you wouldn't have to c=
are. You'd just return an array_view<unique_ptr<T>>, and those =
who wanted to consume it would be a template that takes an appropriate rang=
e. Nobody would be subjected to the details of your memory management (unle=
ss they deliberately choose to be). And thanks to modules, they wouldn't be=
subjected to the horrible compile-times that come along with doing all thi=
s (which is the #1 reason why people avoid doing it today. #2 is the lack o=
f concepts).<br><br>Basically, this would be a solved problem if compile-ti=
me wasn't an issue.<br><br></div><blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;"><div dir=3D"ltr">This issue is making unique_ptr very cumbersome to use.=
Ideally I'd like to just be able to specify memory management once within =
the containing class data members and then pass around array_view<T*>=
everywhere externally, clients not knowing, caring, or recompiling whether=
the view points to a set of managed or unmanaged pointers.</div></blockquo=
te><div><br>Well, that's just not going to happen. std::unique_ptr does not=
(necessarily) have zero overhead. It all depends on the deleter. Plus, tha=
t would require aliasing.<br><br>The only solution here is a container that=
specifically handles memory allocation, like Boost's ptr_vector. But I don=
't think this is a frequent enough problem to have them standardize such a =
special use container.<br></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" 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_3958_689768952.1424744683718--
------=_Part_3957_5663060.1424744683718--
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Mon, 23 Feb 2015 19:26:48 -0800 (PST)
Raw View
------=_Part_4247_258400472.1424748408504
Content-Type: multipart/alternative;
boundary="----=_Part_4248_724798670.1424748408504"
------=_Part_4248_724798670.1424748408504
Content-Type: text/plain; charset=UTF-8
If unique_ptr<T> is untouchable, the other solution could be to make a new
smart pointer class trivial_ptr<T> which is like unique_ptr<T> but only
supporting only a stateless custom deleter and is guaranteed to alias with
T* const. It can provide functions to safety perform the cast. One can
easily move a unique_ptr<T> into and out of trivial_ptr<T>.
class Foo {
public:
array_view<T*> getA() const { return _a.empty() ? {} : { &_a.front()->
alias(), _a.size() };
array_view<T*> getB() const { return _b; }
private:
vector<trivial_ptr<T>> _a;
vector<T*> _b;
};
On Monday, February 23, 2015 at 9:24:43 PM UTC-5, Nicol Bolas wrote:
>
> On Monday, February 23, 2015 at 6:52:17 PM UTC-5, Matthew Fioravante wrote:
>>
>> Sorry to beat a probably dead horse, but I really keep running into this
>> problem over and over again. Even if you aren't using array_view, its still
>> a problem.
>>
>> class Foo {
>> public:
>> const auto& getA() { return a; }
>> const auto& getB() { return b; }
>> private:
>> vector<std::unique_ptr<T>> a;
>> vector<T*> b;
>> }:
>>
>> In order to avoid a copy, we're forced to leak the implementation details
>> that A is managed by unique_ptr but B is not. Even if we decide making a
>> copy is ok, this still means that getA() has to return by value while
>> getB() can continue to return by const reference. The ideal scenario which
>> is just returning array_view<T*> is impossible because there is nowhere to
>> store the copy of a.
>>
>> Both a and b are just vectors of pointers. The fact that a has additional
>> logic tacked on to automatically manage memory is irrelevant to the client
>> of Foo.
>>
>
> But it's very relevant to Foo. And since he's the owner and creator of the
> array, he's the one who decides these things.
>
Yes that's right, but Foo doesn't have to advertise the fact unless asked
for it. Which data is or is not managed may be a part of the Foo
specification, but this information is not necessary for clients requesting
a const view over the data. The fact that its managed by unique_ptr and not
some other unique ownership mechanism is a pure implementation detail which
should not be leaked to clients.
By returning different types, we make it more difficult to write generic
code without templates because we have this artificial dependency leaking
all over the place. Even if foo does manage the resources referred to by
getA(), the resource management may be performed using another data
structure other than the array getA() references. If getA() could return
array_view<T*>, we would have better encapsulation and freedom for the
implementation of Foo.
>
> For all intents and purposes, your problem is the lack of modules in C++.
> Here's what I mean.
>
> What you really want to do is give people a non-modifiable view of your
> stored data. Your users won't care what specific types you may wrap your
> stored data in, so long as they obey certain basic principles (ie: the
> expectations of a pointer to T).
>
> The "correct" way to handle this is with templates. That is, code that
> wants to consume your array_view would be a template, on the array view's
> type (or the template type could be more general, a non-modifiable range of
> pointer-to-T-like objects. Whatever). The problem is that now, all your
> consuming code needs to live in header files. As much any code that just
> passes your stuff along to others. Templates are rather viral like that.
>
> If you had modules, you wouldn't have to care. You'd just return an
> array_view<unique_ptr<T>>, and those who wanted to consume it would be a
> template that takes an appropriate range. Nobody would be subjected to the
> details of your memory management (unless they deliberately choose to be).
> And thanks to modules, they wouldn't be subjected to the horrible
> compile-times that come along with doing all this (which is the #1 reason
> why people avoid doing it today. #2 is the lack of concepts).
>
> Basically, this would be a solved problem if compile-time wasn't an issue.
>
I haven't studied the latest work in modules yet. If I understand
correctly, you're saying with modules basically everything can be a
template and whether or not the range iterates over unique_ptr<T> or T* is
irrelevant because it will just flow though the type system via type
deduction like magic.
This works fine until you need to pass the thing to a third party library
which views a pointer by taking T* by reference. It also burdens all of
your code with more template syntax when it could just be simple function
calls. The more meta-programming you add to your code, the more complex it
becomes and the more time you have to spend making things generic. Finally,
templates generate code. If I have 2 implementations of a function, 1 for
T* and 1 for std::unique_ptr<T> then the template system will generate 2
copies of the same code.
>
> This issue is making unique_ptr very cumbersome to use. Ideally I'd like
>> to just be able to specify memory management once within the containing
>> class data members and then pass around array_view<T*> everywhere
>> externally, clients not knowing, caring, or recompiling whether the view
>> points to a set of managed or unmanaged pointers.
>>
>
> Well, that's just not going to happen. std::unique_ptr does not
> (necessarily) have zero overhead. It all depends on the deleter.
>
If there is a custom or maybe even stateless deleter, I have yet to find a
good reason (other than attaching debugging info) to not restrict
implementations of unique_ptr to store only a T*. Adding a new type like
trivial_ptr<T> seems less optimal than just reusing unique_ptr<T> with a
stateless deleter. The alias() call can be conceptified to reject
unique_ptr's, with stateful deleters.
> Plus, that would require aliasing.
>
Ugly scary aliasing is the most efficient way to solve this problem. On
modern machines, arrays are almost always the most efficient data structure
to store data. array_view<T> brings an extremely flexible range library
like solution for this most ubiquitous and efficient data layout, often
without requiring templates at all.
If you have an array of wrapper<T> stored in memory whose lifetime is
managed by a stateless wrapper type, you need aliasing to efficiently
retrieve a const view over the array of T.
>
> The only solution here is a container that specifically handles memory
> allocation, like Boost's ptr_vector. But I don't think this is a frequent
> enough problem to have them standardize such a special use container.
>
I think the ptr_vector approach is not generic enough. Basically you have
to create a copy of the std::vector<T> specification with some customized
behavior only for pointers. Lifetime management is fully specified by T so
a better solution is just to create a new stateless wrapper type to manage
T* and be aliasable to to T*.
--
---
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_4248_724798670.1424748408504
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">If unique_ptr<T> is untouchable, the other solution =
could be to make a new smart pointer class trivial_ptr<T> which is li=
ke unique_ptr<T> but only supporting only a stateless custom deleter =
and is guaranteed to alias with T* const. It can provide functions to safet=
y perform the cast. One can easily move a unique_ptr<T> into and out =
of trivial_ptr<T>.<div><br></div><div><div class=3D"prettyprint" styl=
e=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; backgroun=
d-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"sub=
prettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">clas=
s</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #606;" class=3D"styled-by-prettify">Foo</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br> </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">public</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br> array_view</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">T</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">*></span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> getA</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">con=
st</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> _a</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">empty</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">?<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">{}</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">&</span><span style=3D"color: #000;" class=3D"styled-by-prettify">_a<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><fo=
nt color=3D"#000000"><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">front</span></font><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">()-></span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">alias</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()=
,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> _a</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">size</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br> array_view</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">T</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">*></span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> getB</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">con=
st</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> _b</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br> </span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">private</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br> =
; vector</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify"><</span><span style=3D"color: #000;" class=3D"styled-by-prettify">t=
rivial_ptr</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
<</span><span style=3D"color: #000;" class=3D"styled-by-prettify">T</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">>></span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> _a</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br> vector</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">*></span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> _b</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">};</span></div></code></div><br><div><br></div><div><br>On Mo=
nday, February 23, 2015 at 9:24:43 PM UTC-5, Nicol Bolas wrote:<blockquote =
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1p=
x #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">On Monday, February 23, 2=
015 at 6:52:17 PM UTC-5, Matthew Fioravante wrote:<blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr">Sorry to beat a probably dead horse, but I =
really keep running into this problem over and over again. Even if you aren=
't using array_view, its still a problem.<br><br><div style=3D"background-c=
olor:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;bord=
er-width:1px;word-wrap:break-word"><code><div><span style=3D"color:#008">cl=
ass</span><span style=3D"color:#000"> </span><span style=3D"color:#606">Foo=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</spa=
n><span style=3D"color:#000"><br></span><span style=3D"color:#008">public</=
span><span style=3D"color:#660">:</span><span style=3D"color:#000"><br>&nbs=
p; </span><span style=3D"color:#008">const</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">auto</span><span style=3D"color:#660">&=
amp;</span><span style=3D"color:#000"> getA</span><span style=3D"color:#660=
">()</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#008">return<=
/span><span style=3D"color:#000"> a</span><span style=3D"color:#660">;</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#660">}</span><sp=
an style=3D"color:#000"><br> </span><span style=3D"color:#008">const<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#008">auto</s=
pan><span style=3D"color:#660">&</span><span style=3D"color:#000"> getB=
</span><span style=3D"color:#660">()</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#660">{</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#008">return</span><span style=3D"color:#000"> b</span><=
span style=3D"color:#660">;</span><span style=3D"color:#000"> </span><span =
style=3D"color:#660">}</span><span style=3D"color:#000"><br></span><span st=
yle=3D"color:#008">private</span><span style=3D"color:#660">:</span><span s=
tyle=3D"color:#000"><br> vector</span><span style=3D"color:#660"><=
</span><span style=3D"color:#000">std</span><span style=3D"color:#660">::</=
span><span style=3D"color:#000">unique_ptr</span><span style=3D"color:#660"=
><</span><span style=3D"color:#000">T</span><span style=3D"color:#660">&=
gt;></span><span style=3D"color:#000"> a</span><span style=3D"color:#660=
">;</span><span style=3D"color:#000"><br> vector</span><span style=3D=
"color:#660"><</span><span style=3D"color:#000">T</span><span style=3D"c=
olor:#660">*></span><span style=3D"color:#000"> b</span><span style=3D"c=
olor:#660">;</span><span style=3D"color:#000"><br></span><span style=3D"col=
or:#660">}:</span></div></code></div><br>In order to avoid a copy, we're fo=
rced to leak the implementation details that A is managed by unique_ptr but=
B is not. Even if we decide making a copy is ok, this still means that get=
A() has to return by value while getB() can continue to return by const ref=
erence. The ideal scenario which is just returning array_view<T*> is =
impossible because there is nowhere to store the copy of a.<br><br>Both a a=
nd b are just vectors of pointers. The fact that a has additional logic tac=
ked on to automatically manage memory is irrelevant to the client of Foo.<b=
r></div></blockquote><div><br>But it's very relevant to Foo. And since he's=
the owner and creator of the array, he's the one who decides these things.=
<br></div></div></blockquote><div><br></div><div>Yes that's right, but Foo =
doesn't have to advertise the fact unless asked for it. Which data is or is=
not managed may be a part of the Foo specification, but this information i=
s not necessary for clients requesting a const view over the data. The fact=
that its managed by unique_ptr and not some other unique ownership mechani=
sm is a pure implementation detail which should not be leaked to clients.</=
div><div><br></div><div>By returning different types, we make it more diffi=
cult to write generic code without templates because we have this artificia=
l dependency leaking all over the place. Even if foo does manage the resour=
ces referred to by getA(), the resource management may be performed using a=
nother data structure other than the array getA() references. If getA() cou=
ld return array_view<T*>, we would have better encapsulation and free=
dom for the implementation of Foo.</div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;"><div dir=3D"ltr"><div><br>For all intents and purposes, your prob=
lem is the lack of modules in C++. Here's what I mean.<br><br>What you real=
ly want to do is give people a non-modifiable view of your stored data. You=
r users won't care what specific types you may wrap your stored data in, so=
long as they obey certain basic principles (ie: the expectations of a poin=
ter to T).<br><br>The "correct" way to handle this is with templates. That =
is, code that wants to consume your array_view would be a template, on the =
array view's type (or the template type could be more general, a non-modifi=
able range of pointer-to-T-like objects. Whatever). The problem is that now=
, all your consuming code needs to live in header files. As much any code t=
hat just passes your stuff along to others. Templates are rather viral like=
that.<br><br>If you had modules, you wouldn't have to care. You'd just ret=
urn an array_view<unique_ptr<T>>, and those who wanted to consu=
me it would be a template that takes an appropriate range. Nobody would be =
subjected to the details of your memory management (unless they deliberatel=
y choose to be). And thanks to modules, they wouldn't be subjected to the h=
orrible compile-times that come along with doing all this (which is the #1 =
reason why people avoid doing it today. #2 is the lack of concepts).<br><br=
>Basically, this would be a solved problem if compile-time wasn't an issue.=
<br></div></div></blockquote><div><br></div><div>I haven't studied the late=
st work in modules yet. If I understand correctly, you're saying with modul=
es basically everything can be a template and whether or not the range iter=
ates over unique_ptr<T> or T* is irrelevant because it will just flow=
though the type system via type deduction like magic.</div><div><br></div>=
<div>This works fine until you need to pass the thing to a third party libr=
ary which views a pointer by taking T* by reference. It also burdens all of=
your code with more template syntax when it could just be simple function =
calls. The more meta-programming you add to your code, the more complex it =
becomes and the more time you have to spend making things generic. <sp=
an style=3D"font-size: 13px;">Finally, templates generate code. If I have 2=
implementations of a function, 1 for T* and 1 for std::unique_ptr<T>=
then the template system will generate 2 copies of the same code.</span></=
div><div> </div><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0=
;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D=
"ltr">This issue is making unique_ptr very cumbersome to use. Ideally I'd l=
ike to just be able to specify memory management once within the containing=
class data members and then pass around array_view<T*> everywhere ex=
ternally, clients not knowing, caring, or recompiling whether the view poin=
ts to a set of managed or unmanaged pointers.</div></blockquote><div><br>We=
ll, that's just not going to happen. std::unique_ptr does not (necessarily)=
have zero overhead. It all depends on the deleter. </div></div></blockquot=
e><div><br>If there is a custom or maybe even stateless deleter, I have yet=
to find a good reason (other than attaching debugging info) to not restric=
t implementations of unique_ptr to store only a T*. Adding a new type like =
trivial_ptr<T> seems less optimal than just reusing unique_ptr<T&g=
t; with a stateless deleter. The alias() call can be conceptified to reject=
unique_ptr's, with stateful deleters.</div><div> </div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px =
#ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>Plus, that would requi=
re aliasing.<br></div></div></blockquote><div><br></div><div>Ugly scary ali=
asing is the most efficient way to solve this problem. On modern machines, =
arrays are almost always the most efficient data structure to store data. a=
rray_view<T> brings an extremely flexible range library like solution=
for this most ubiquitous and efficient data layout, often without requirin=
g templates at all.</div><div><br></div><div>If you have an array of wrappe=
r<T> stored in memory whose lifetime is managed by a stateless wrappe=
r type, you need aliasing to efficiently retrieve a const view over the arr=
ay of T.</div><div> </div><blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
><div dir=3D"ltr"><div><br>The only solution here is a container that speci=
fically handles memory allocation, like Boost's ptr_vector. But I don't thi=
nk this is a frequent enough problem to have them standardize such a specia=
l use container.<br></div></div></blockquote><div><br></div><span style=3D"=
font-size: 13.1428575515747px;">I think the ptr_vector approach is not gene=
ric enough. Basically you have to create a copy of the std::vector<T>=
specification with some customized behavior only for pointers. Lifetime ma=
nagement is fully specified by T so a better solution is just to create a n=
ew stateless wrapper type to manage T* and be aliasable to to T*.</span><br=
style=3D"font-size: 13.1428575515747px;"><div> </div></div></div></di=
v>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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_4248_724798670.1424748408504--
------=_Part_4247_258400472.1424748408504--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 24 Feb 2015 06:39:41 -0800 (PST)
Raw View
------=_Part_546_797943008.1424788781308
Content-Type: multipart/alternative;
boundary="----=_Part_547_2140243588.1424788781309"
------=_Part_547_2140243588.1424788781309
Content-Type: text/plain; charset=UTF-8
On Monday, February 23, 2015 at 10:26:48 PM UTC-5, Matthew Fioravante wrote:
>
> But it's very relevant to Foo. And since he's the owner and creator of the
>> array, he's the one who decides these things.
>>
>
> Yes that's right, but Foo doesn't have to advertise the fact unless asked
> for it. Which data is or is not managed may be a part of the Foo
> specification, but this information is not necessary for clients requesting
> a const view over the data. The fact that its managed by unique_ptr and not
> some other unique ownership mechanism is a pure implementation detail which
> should not be leaked to clients.
>
> By returning different types, we make it more difficult to write generic
> code without templates because we have this artificial dependency leaking
> all over the place. Even if foo does manage the resources referred to by
> getA(), the resource management may be performed using another data
> structure other than the array getA() references. If getA() could return
> array_view<T*>, we would have better encapsulation and freedom for the
> implementation of Foo.
>
Foo wouldn't be free to use an internal implementation that wasn't
magically aliasable to a C-array of T. For example, it couldn't suddenly
decide that it needs shared ownership.
If your consuming code was *fully* generic (ie: templates), then Foo would
*truly* be free to implement whatever it wanted.
> For all intents and purposes, your problem is the lack of modules in C++.
>> Here's what I mean.
>>
>> What you really want to do is give people a non-modifiable view of your
>> stored data. Your users won't care what specific types you may wrap your
>> stored data in, so long as they obey certain basic principles (ie: the
>> expectations of a pointer to T).
>>
>> The "correct" way to handle this is with templates. That is, code that
>> wants to consume your array_view would be a template, on the array view's
>> type (or the template type could be more general, a non-modifiable range of
>> pointer-to-T-like objects. Whatever). The problem is that now, all your
>> consuming code needs to live in header files. As much any code that just
>> passes your stuff along to others. Templates are rather viral like that.
>>
>> If you had modules, you wouldn't have to care. You'd just return an
>> array_view<unique_ptr<T>>, and those who wanted to consume it would be a
>> template that takes an appropriate range. Nobody would be subjected to the
>> details of your memory management (unless they deliberately choose to be).
>> And thanks to modules, they wouldn't be subjected to the horrible
>> compile-times that come along with doing all this (which is the #1 reason
>> why people avoid doing it today. #2 is the lack of concepts).
>>
>> Basically, this would be a solved problem if compile-time wasn't an issue.
>>
>
> I haven't studied the latest work in modules yet. If I understand
> correctly, you're saying with modules basically everything can be a
> template and whether or not the range iterates over unique_ptr<T> or T* is
> irrelevant because it will just flow though the type system via type
> deduction like magic.
>
> This works fine until you need to pass the thing to a third party library
> which views a pointer by taking T* by reference.
>
Yes, that happens. But how is that any different from *any* interface with
a third party library? There are always going to be libraries that use
something odd in their interfaces, that requires translation. What if
you're trying to stick that array into a Lua table or a Python array? You
need some form of translation.
You would have this exact problem if 'Foo' stopped using a contiguous,
alias-able array. Isn't that the whole point? To not have third-party
libraries place arbitrary restrictions on your data structures (like "you
must use a contiguous array of pointers to some type")?
> It also burdens all of your code with more template syntax when it could
> just be simple function calls. The more meta-programming you add to your
> code, the more complex it becomes and the more time you have to spend
> making things generic.
>
That's the point of concepts; it makes "template syntax" not be a "burden".
The point of modules is to make using "more template syntax" practical.
So my original point stands. It's not that you don't have a solution in
C++. It's that the C++ solution has these burdens on it that shouldn't be
there. Once those burdens are eased and/or eliminated, then your problem is
effectively solved.
>
>> This issue is making unique_ptr very cumbersome to use. Ideally I'd like
>>> to just be able to specify memory management once within the containing
>>> class data members and then pass around array_view<T*> everywhere
>>> externally, clients not knowing, caring, or recompiling whether the view
>>> points to a set of managed or unmanaged pointers.
>>>
>>
>> Well, that's just not going to happen. std::unique_ptr does not
>> (necessarily) have zero overhead. It all depends on the deleter.
>>
>
> If there is a custom or maybe even stateless deleter, I have yet to find a
> good reason (other than attaching debugging info) to not restrict
> implementations of unique_ptr to store only a T*. Adding a new type like
> trivial_ptr<T> seems less optimal than just reusing unique_ptr<T> with a
> stateless deleter. The alias() call can be conceptified to reject
> unique_ptr's, with stateful deleters.
>
>
>> Plus, that would require aliasing.
>>
>
> Ugly scary aliasing is the most efficient way to solve this problem. On
> modern machines, arrays are almost always the most efficient data structure
> to store data. array_view<T> brings an extremely flexible range library
> like solution for this most ubiquitous and efficient data layout, often
> without requiring templates at all.
>
> If you have an array of wrapper<T> stored in memory whose lifetime is
> managed by a stateless wrapper type, you need aliasing to efficiently
> retrieve a const view over the array of T.
>
That would require aliasing. Which is *forbidden* in C++, regardless of the
size or representation of whatever wrapper you're using. Therefore, what
you're asking for is a *language change*, not merely a library thing.
And breaking strict aliasing just ain't gonna happen.
You can either keep wanting something you're not going to get, or work with
what you actually have. I prefer option 2.
>
>
>>
>> The only solution here is a container that specifically handles memory
>> allocation, like Boost's ptr_vector. But I don't think this is a frequent
>> enough problem to have them standardize such a special use container.
>>
>
> I think the ptr_vector approach is not generic enough. Basically you have
> to create a copy of the std::vector<T> specification with some customized
> behavior only for pointers. Lifetime management is fully specified by T so
> a better solution is just to create a new stateless wrapper type to manage
> T* and be aliasable to to T*.
>
Why is it "not generic enough"? Sure, it specifically supports only unique
ownership, but... so what? What other kind of "lifetime management" are you
going to be able to do that is both stateless and (theoretically) aliasable
to T*?
ptr_vector is specifically *designed* to solve your exact problem. And it
doesn't require breaking strict aliasing (which again, is *not gonna happen*).
So why would you not use it?
--
---
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_547_2140243588.1424788781309
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, February 23, 2015 at 10:26:48 PM UTC-5, Matthew=
Fioravante wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
ltr"><div><div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><di=
v>But it's very relevant to Foo. And since he's the owner and creator of th=
e array, he's the one who decides these things.<br></div></div></blockquote=
><div><br></div><div>Yes that's right, but Foo doesn't have to advertise th=
e fact unless asked for it. Which data is or is not managed may be a part o=
f the Foo specification, but this information is not necessary for clients =
requesting a const view over the data. The fact that its managed by unique_=
ptr and not some other unique ownership mechanism is a pure implementation =
detail which should not be leaked to clients.</div><div><br></div><div>By r=
eturning different types, we make it more difficult to write generic code w=
ithout templates because we have this artificial dependency leaking all ove=
r the place. Even if foo does manage the resources referred to by getA(), t=
he resource management may be performed using another data structure other =
than the array getA() references. If getA() could return array_view<T*&g=
t;, we would have better encapsulation and freedom for the implementation o=
f Foo.</div></div></div></div></blockquote><div><br>Foo wouldn't be free to=
use an internal implementation that wasn't magically aliasable to a C-arra=
y of T. For example, it couldn't suddenly decide that it needs shared owner=
ship.<br><br>If your consuming code was <i>fully</i> generic (ie: templates=
), then Foo would <i>truly</i> be free to implement whatever it wanted.<br>=
</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><=
div><div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.=
8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>For =
all intents and purposes, your problem is the lack of modules in C++. Here'=
s what I mean.<br><br>What you really want to do is give people a non-modif=
iable view of your stored data. Your users won't care what specific types y=
ou may wrap your stored data in, so long as they obey certain basic princip=
les (ie: the expectations of a pointer to T).<br><br>The "correct" way to h=
andle this is with templates. That is, code that wants to consume your arra=
y_view would be a template, on the array view's type (or the template type =
could be more general, a non-modifiable range of pointer-to-T-like objects.=
Whatever). The problem is that now, all your consuming code needs to live =
in header files. As much any code that just passes your stuff along to othe=
rs. Templates are rather viral like that.<br><br>If you had modules, you wo=
uldn't have to care. You'd just return an array_view<unique_ptr<T>=
>, and those who wanted to consume it would be a template that takes an =
appropriate range. Nobody would be subjected to the details of your memory =
management (unless they deliberately choose to be). And thanks to modules, =
they wouldn't be subjected to the horrible compile-times that come along wi=
th doing all this (which is the #1 reason why people avoid doing it today. =
#2 is the lack of concepts).<br><br>Basically, this would be a solved probl=
em if compile-time wasn't an issue.<br></div></div></blockquote><div><br></=
div><div>I haven't studied the latest work in modules yet. If I understand =
correctly, you're saying with modules basically everything can be a templat=
e and whether or not the range iterates over unique_ptr<T> or T* is i=
rrelevant because it will just flow though the type system via type deducti=
on like magic.</div><div><br></div><div>This works fine until you need to p=
ass the thing to a third party library which views a pointer by taking T* b=
y reference.</div></div></div></div></blockquote><div><br>Yes, that happens=
.. But how is that any different from <i>any</i> interface with a third part=
y library? There are always going to be libraries that use something odd in=
their interfaces, that requires translation. What if you're trying to stic=
k that array into a Lua table or a Python array? You need some form of tran=
slation.<br><br>You would have this exact problem if 'Foo' stopped using a =
contiguous, alias-able array. Isn't that the whole point? To not have third=
-party libraries place arbitrary restrictions on your data structures (like=
"you must use a contiguous array of pointers to some type")?<br> </di=
v><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div><=
div>It also burdens all of your code with more template syntax when it coul=
d just be simple function calls. The more meta-programming you add to your =
code, the more complex it becomes and the more time you have to spend makin=
g things generic.</div></div></div></div></blockquote><div><br>That's the p=
oint of concepts; it makes "template syntax" not be a "burden". The point o=
f modules is to make using "more template syntax" practical.<br><br>So my o=
riginal point stands. It's not that you don't have a solution in C++. It's =
that the C++ solution has these burdens on it that shouldn't be there. Once=
those burdens are eased and/or eliminated, then your problem is effectivel=
y solved.<br> </div><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div =
dir=3D"ltr"><div><div><blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
>This issue is making unique_ptr very cumbersome to use. Ideally I'd like t=
o just be able to specify memory management once within the containing clas=
s data members and then pass around array_view<T*> everywhere externa=
lly, clients not knowing, caring, or recompiling whether the view points to=
a set of managed or unmanaged pointers.</div></blockquote><div><br>Well, t=
hat's just not going to happen. std::unique_ptr does not (necessarily) have=
zero overhead. It all depends on the deleter. </div></div></blockquote><di=
v><br>If there is a custom or maybe even stateless deleter, I have yet to f=
ind a good reason (other than attaching debugging info) to not restrict imp=
lementations of unique_ptr to store only a T*. Adding a new type like trivi=
al_ptr<T> seems less optimal than just reusing unique_ptr<T> wi=
th a stateless deleter. The alias() call can be conceptified to reject uniq=
ue_ptr's, with stateful deleters.</div><div> </div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div>Plus, that would require alias=
ing.<br></div></div></blockquote><div><br></div><div>Ugly scary aliasing is=
the most efficient way to solve this problem. On modern machines, arrays a=
re almost always the most efficient data structure to store data. array_vie=
w<T> brings an extremely flexible range library like solution for thi=
s most ubiquitous and efficient data layout, often without requiring templa=
tes at all.</div><div><br></div><div>If you have an array of wrapper<T&g=
t; stored in memory whose lifetime is managed by a stateless wrapper type, =
you need aliasing to efficiently retrieve a const view over the array of T.=
</div></div></div></div></blockquote><div><br>That would require aliasing. =
Which is <i>forbidden</i> in C++, regardless of the size or representation =
of whatever wrapper you're using. Therefore, what you're asking for is a <i=
>language change</i>, not merely a library thing.<br><br>And breaking stric=
t aliasing just ain't gonna happen.<br><br>You can either keep wanting some=
thing you're not going to get, or work with what you actually have. I prefe=
r option 2.<br> </div><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr"><div><div><div> </div><blockquote class=3D"gmail_quote" =
style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left=
:1ex"><div dir=3D"ltr"><div><br>The only solution here is a container that =
specifically handles memory allocation, like Boost's ptr_vector. But I don'=
t think this is a frequent enough problem to have them standardize such a s=
pecial use container.<br></div></div></blockquote><div><br></div><span styl=
e=3D"font-size:13.1428575515747px">I think the ptr_vector approach is not g=
eneric enough. Basically you have to create a copy of the std::vector<T&=
gt; specification with some customized behavior only for pointers. Lifetime=
management is fully specified by T so a better solution is just to create =
a new stateless wrapper type to manage T* and be aliasable to to T*.</span>=
</div></div></div></blockquote><div><br>Why is it "not generic enough"? Sur=
e, it specifically supports only unique ownership, but... so what? What oth=
er kind of "lifetime management" are you going to be able to do that is bot=
h stateless and (theoretically) aliasable to T*?<br><br>ptr_vector is speci=
fically <i>designed</i> to solve your exact problem. And it doesn't require=
breaking strict aliasing (which again, is <i>not gonna happen</i>). So why=
would you not use it?<br></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" 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_547_2140243588.1424788781309--
------=_Part_546_797943008.1424788781308--
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Fri, 27 Feb 2015 19:03:27 -0800 (PST)
Raw View
------=_Part_1281_1763904893.1425092607980
Content-Type: multipart/alternative;
boundary="----=_Part_1282_2085273463.1425092607980"
------=_Part_1282_2085273463.1425092607980
Content-Type: text/plain; charset=UTF-8
On Tuesday, February 24, 2015 at 9:39:41 AM UTC-5, Nicol Bolas wrote:
>
> On Monday, February 23, 2015 at 10:26:48 PM UTC-5, Matthew Fioravante
> wrote:
>>
>> But it's very relevant to Foo. And since he's the owner and creator of
>>> the array, he's the one who decides these things.
>>>
>>
>> Yes that's right, but Foo doesn't have to advertise the fact unless asked
>> for it. Which data is or is not managed may be a part of the Foo
>> specification, but this information is not necessary for clients requesting
>> a const view over the data. The fact that its managed by unique_ptr and not
>> some other unique ownership mechanism is a pure implementation detail which
>> should not be leaked to clients.
>>
>> By returning different types, we make it more difficult to write generic
>> code without templates because we have this artificial dependency leaking
>> all over the place. Even if foo does manage the resources referred to by
>> getA(), the resource management may be performed using another data
>> structure other than the array getA() references. If getA() could return
>> array_view<T*>, we would have better encapsulation and freedom for the
>> implementation of Foo.
>>
>
> Foo wouldn't be free to use an internal implementation that wasn't
> magically aliasable to a C-array of T. For example, it couldn't suddenly
> decide that it needs shared ownership.
>
> If your consuming code was *fully* generic (ie: templates), then Foo
> would *truly* be free to implement whatever it wanted.
>
>
>> For all intents and purposes, your problem is the lack of modules in C++.
>>> Here's what I mean.
>>>
>>> What you really want to do is give people a non-modifiable view of your
>>> stored data. Your users won't care what specific types you may wrap your
>>> stored data in, so long as they obey certain basic principles (ie: the
>>> expectations of a pointer to T).
>>>
>>> The "correct" way to handle this is with templates. That is, code that
>>> wants to consume your array_view would be a template, on the array view's
>>> type (or the template type could be more general, a non-modifiable range of
>>> pointer-to-T-like objects. Whatever). The problem is that now, all your
>>> consuming code needs to live in header files. As much any code that just
>>> passes your stuff along to others. Templates are rather viral like that.
>>>
>>> If you had modules, you wouldn't have to care. You'd just return an
>>> array_view<unique_ptr<T>>, and those who wanted to consume it would be a
>>> template that takes an appropriate range. Nobody would be subjected to the
>>> details of your memory management (unless they deliberately choose to be).
>>> And thanks to modules, they wouldn't be subjected to the horrible
>>> compile-times that come along with doing all this (which is the #1 reason
>>> why people avoid doing it today. #2 is the lack of concepts).
>>>
>>> Basically, this would be a solved problem if compile-time wasn't an
>>> issue.
>>>
>>
>> I haven't studied the latest work in modules yet. If I understand
>> correctly, you're saying with modules basically everything can be a
>> template and whether or not the range iterates over unique_ptr<T> or T* is
>> irrelevant because it will just flow though the type system via type
>> deduction like magic.
>>
>> This works fine until you need to pass the thing to a third party library
>> which views a pointer by taking T* by reference.
>>
>
> Yes, that happens. But how is that any different from *any* interface
> with a third party library? There are always going to be libraries that use
> something odd in their interfaces, that requires translation. What if
> you're trying to stick that array into a Lua table or a Python array? You
> need some form of translation.
>
> You would have this exact problem if 'Foo' stopped using a contiguous,
> alias-able array. Isn't that the whole point? To not have third-party
> libraries place arbitrary restrictions on your data structures (like "you
> must use a contiguous array of pointers to some type")?
>
>
>> It also burdens all of your code with more template syntax when it could
>> just be simple function calls. The more meta-programming you add to your
>> code, the more complex it becomes and the more time you have to spend
>> making things generic.
>>
>
> That's the point of concepts; it makes "template syntax" not be a
> "burden". The point of modules is to make using "more template syntax"
> practical.
>
> So my original point stands. It's not that you don't have a solution in
> C++. It's that the C++ solution has these burdens on it that shouldn't be
> there. Once those burdens are eased and/or eliminated, then your problem is
> effectively solved.
>
>
>>
>>> This issue is making unique_ptr very cumbersome to use. Ideally I'd like
>>>> to just be able to specify memory management once within the containing
>>>> class data members and then pass around array_view<T*> everywhere
>>>> externally, clients not knowing, caring, or recompiling whether the view
>>>> points to a set of managed or unmanaged pointers.
>>>>
>>>
>>> Well, that's just not going to happen. std::unique_ptr does not
>>> (necessarily) have zero overhead. It all depends on the deleter.
>>>
>>
>> If there is a custom or maybe even stateless deleter, I have yet to find
>> a good reason (other than attaching debugging info) to not restrict
>> implementations of unique_ptr to store only a T*. Adding a new type like
>> trivial_ptr<T> seems less optimal than just reusing unique_ptr<T> with a
>> stateless deleter. The alias() call can be conceptified to reject
>> unique_ptr's, with stateful deleters.
>>
>>
>>> Plus, that would require aliasing.
>>>
>>
>> Ugly scary aliasing is the most efficient way to solve this problem. On
>> modern machines, arrays are almost always the most efficient data structure
>> to store data. array_view<T> brings an extremely flexible range library
>> like solution for this most ubiquitous and efficient data layout, often
>> without requiring templates at all.
>>
>> If you have an array of wrapper<T> stored in memory whose lifetime is
>> managed by a stateless wrapper type, you need aliasing to efficiently
>> retrieve a const view over the array of T.
>>
>
> That would require aliasing. Which is *forbidden* in C++, regardless of
> the size or representation of whatever wrapper you're using. Therefore,
> what you're asking for is a *language change*, not merely a library thing.
>
> And breaking strict aliasing just ain't gonna happen.
>
> You can either keep wanting something you're not going to get, or work
> with what you actually have. I prefer option 2.
>
>
>>
>>
>>>
>>> The only solution here is a container that specifically handles memory
>>> allocation, like Boost's ptr_vector. But I don't think this is a frequent
>>> enough problem to have them standardize such a special use container.
>>>
>>
>> I think the ptr_vector approach is not generic enough. Basically you have
>> to create a copy of the std::vector<T> specification with some customized
>> behavior only for pointers. Lifetime management is fully specified by T so
>> a better solution is just to create a new stateless wrapper type to manage
>> T* and be aliasable to to T*.
>>
>
> Why is it "not generic enough"?
>
If we have ptr_vector, why not other kinds of ptr_ data structures? Are
absolutely sure vector is the only data structure worth this specialization?
> Sure, it specifically supports only unique ownership, but... so what?
>
What other kind of "lifetime management" are you going to be able to do
> that is both stateless and (theoretically) aliasable to T*?
>
Any stateless memory allocator can be used in this context.
>
> ptr_vector is specifically *designed* to solve your exact problem. And it
> doesn't require breaking strict aliasing (which again, is *not gonna
> happen*). So why would you not use it?
>
If ptr_vector is the only possible solution then it will do because at
least it solves the immediate problem.
--
---
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_1282_2085273463.1425092607980
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, February 24, 2015 at 9:39:41 AM UTC-5,=
Nicol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr">On Monday, February 23, 2015 at 10:26:48 PM UTC-5, Matthew Fioravante=
wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div><=
blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border=
-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>But it's very =
relevant to Foo. And since he's the owner and creator of the array, he's th=
e one who decides these things.<br></div></div></blockquote><div><br></div>=
<div>Yes that's right, but Foo doesn't have to advertise the fact unless as=
ked for it. Which data is or is not managed may be a part of the Foo specif=
ication, but this information is not necessary for clients requesting a con=
st view over the data. The fact that its managed by unique_ptr and not some=
other unique ownership mechanism is a pure implementation detail which sho=
uld not be leaked to clients.</div><div><br></div><div>By returning differe=
nt types, we make it more difficult to write generic code without templates=
because we have this artificial dependency leaking all over the place. Eve=
n if foo does manage the resources referred to by getA(), the resource mana=
gement may be performed using another data structure other than the array g=
etA() references. If getA() could return array_view<T*>, we would hav=
e better encapsulation and freedom for the implementation of Foo.</div></di=
v></div></div></blockquote><div><br>Foo wouldn't be free to use an internal=
implementation that wasn't magically aliasable to a C-array of T. For exam=
ple, it couldn't suddenly decide that it needs shared ownership.<br><br>If =
your consuming code was <i>fully</i> generic (ie: templates), then Foo woul=
d <i>truly</i> be free to implement whatever it wanted.<br> </div><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div><blockquote =
class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #=
ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>For all intents and purpo=
ses, your problem is the lack of modules in C++. Here's what I mean.<br><br=
>What you really want to do is give people a non-modifiable view of your st=
ored data. Your users won't care what specific types you may wrap your stor=
ed data in, so long as they obey certain basic principles (ie: the expectat=
ions of a pointer to T).<br><br>The "correct" way to handle this is with te=
mplates. That is, code that wants to consume your array_view would be a tem=
plate, on the array view's type (or the template type could be more general=
, a non-modifiable range of pointer-to-T-like objects. Whatever). The probl=
em is that now, all your consuming code needs to live in header files. As m=
uch any code that just passes your stuff along to others. Templates are rat=
her viral like that.<br><br>If you had modules, you wouldn't have to care. =
You'd just return an array_view<unique_ptr<T>>, and those who w=
anted to consume it would be a template that takes an appropriate range. No=
body would be subjected to the details of your memory management (unless th=
ey deliberately choose to be). And thanks to modules, they wouldn't be subj=
ected to the horrible compile-times that come along with doing all this (wh=
ich is the #1 reason why people avoid doing it today. #2 is the lack of con=
cepts).<br><br>Basically, this would be a solved problem if compile-time wa=
sn't an issue.<br></div></div></blockquote><div><br></div><div>I haven't st=
udied the latest work in modules yet. If I understand correctly, you're say=
ing with modules basically everything can be a template and whether or not =
the range iterates over unique_ptr<T> or T* is irrelevant because it =
will just flow though the type system via type deduction like magic.</div><=
div><br></div><div>This works fine until you need to pass the thing to a th=
ird party library which views a pointer by taking T* by reference.</div></d=
iv></div></div></blockquote><div><br>Yes, that happens. But how is that any=
different from <i>any</i> interface with a third party library? There are =
always going to be libraries that use something odd in their interfaces, th=
at requires translation. What if you're trying to stick that array into a L=
ua table or a Python array? You need some form of translation.<br><br>You w=
ould have this exact problem if 'Foo' stopped using a contiguous, alias-abl=
e array. Isn't that the whole point? To not have third-party libraries plac=
e arbitrary restrictions on your data structures (like "you must use a cont=
iguous array of pointers to some type")?<br> </div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div><div><div>It also burdens all =
of your code with more template syntax when it could just be simple functio=
n calls. The more meta-programming you add to your code, the more complex i=
t becomes and the more time you have to spend making things generic.</div><=
/div></div></div></blockquote><div><br>That's the point of concepts; it mak=
es "template syntax" not be a "burden". The point of modules is to make usi=
ng "more template syntax" practical.<br><br>So my original point stands. It=
's not that you don't have a solution in C++. It's that the C++ solution ha=
s these burdens on it that shouldn't be there. Once those burdens are eased=
and/or eliminated, then your problem is effectively solved.<br> </div=
><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br></div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
#ccc solid;padding-left:1ex"><div dir=3D"ltr">This issue is making unique_=
ptr very cumbersome to use. Ideally I'd like to just be able to specify mem=
ory management once within the containing class data members and then pass =
around array_view<T*> everywhere externally, clients not knowing, car=
ing, or recompiling whether the view points to a set of managed or unmanage=
d pointers.</div></blockquote><div><br>Well, that's just not going to happe=
n. std::unique_ptr does not (necessarily) have zero overhead. It all depend=
s on the deleter. </div></div></blockquote><div><br>If there is a custom or=
maybe even stateless deleter, I have yet to find a good reason (other than=
attaching debugging info) to not restrict implementations of unique_ptr to=
store only a T*. Adding a new type like trivial_ptr<T> seems less op=
timal than just reusing unique_ptr<T> with a stateless deleter. The a=
lias() call can be conceptified to reject unique_ptr's, with stateful delet=
ers.</div><div> </div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div>Plus, that would require aliasing.<br></div></div></blockquot=
e><div><br></div><div>Ugly scary aliasing is the most efficient way to solv=
e this problem. On modern machines, arrays are almost always the most effic=
ient data structure to store data. array_view<T> brings an extremely =
flexible range library like solution for this most ubiquitous and efficient=
data layout, often without requiring templates at all.</div><div><br></div=
><div>If you have an array of wrapper<T> stored in memory whose lifet=
ime is managed by a stateless wrapper type, you need aliasing to efficientl=
y retrieve a const view over the array of T.</div></div></div></div></block=
quote><div><br>That would require aliasing. Which is <i>forbidden</i> in C+=
+, regardless of the size or representation of whatever wrapper you're usin=
g. Therefore, what you're asking for is a <i>language change</i>, not merel=
y a library thing.<br><br>And breaking strict aliasing just ain't gonna hap=
pen.<br><br>You can either keep wanting something you're not going to get, =
or work with what you actually have. I prefer option 2.<br> </div><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div><div> <=
/div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br>The =
only solution here is a container that specifically handles memory allocati=
on, like Boost's ptr_vector. But I don't think this is a frequent enough pr=
oblem to have them standardize such a special use container.<br></div></div=
></blockquote><div><br></div><span style=3D"font-size:13.1428575515747px">I=
think the ptr_vector approach is not generic enough. Basically you have to=
create a copy of the std::vector<T> specification with some customiz=
ed behavior only for pointers. Lifetime management is fully specified by T =
so a better solution is just to create a new stateless wrapper type to mana=
ge T* and be aliasable to to T*.</span></div></div></div></blockquote><div>=
<br>Why is it "not generic enough"? </div></div></blockquote><div><br></div=
><div>If we have ptr_vector, why not other kinds of ptr_ data structures? A=
re absolutely sure vector is the only data structure worth this specializat=
ion?</div><div><br></div><div> </div><blockquote class=3D"gmail_quote"=
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-=
left: 1ex;"><div dir=3D"ltr"><div>Sure, it specifically supports only uniqu=
e ownership, but... so what?</div></div></blockquote><blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;"><div dir=3D"ltr"><div>What other kind of "lifetime m=
anagement" are you going to be able to do that is both stateless and (theor=
etically) aliasable to T*?<br></div></div></blockquote><div><br></div><div>=
Any stateless memory allocator can be used in this context.</div><div> =
;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><=
br>ptr_vector is specifically <i>designed</i> to solve your exact problem. =
And it doesn't require breaking strict aliasing (which again, is <i>not gon=
na happen</i>). So why would you not use it?<br></div></div></blockquote><d=
iv><br></div><div>If ptr_vector is the only possible solution then it will =
do because at least it solves the immediate problem.</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" 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_1282_2085273463.1425092607980--
------=_Part_1281_1763904893.1425092607980--
.
Author: inkwizytoryankes@gmail.com
Date: Sat, 28 Feb 2015 05:35:49 -0800 (PST)
Raw View
------=_Part_1564_2079094591.1425130549821
Content-Type: multipart/alternative;
boundary="----=_Part_1565_1636370600.1425130549821"
------=_Part_1565_1636370600.1425130549821
Content-Type: text/plain; charset=UTF-8
I think is possible to create `unique_container` that will warp around
normal containers and have limited interface to maintain invariants.
Simplest and dummiest implementation will look like:
template<typename Container>
class unique_container
{
Container c;
public:
template<typename... T>
void emplace_back(T... t) { c.push_back(new Container::value_type(std::
forward<T>(t)...)); }
void erase(size_t i) { delete c[i]; c.erase(i); }
const Container& get() const { returns c; }
~unique_container() { for(auto& i : c) { delete i; } }
};
On Saturday, February 28, 2015 at 4:03:28 AM UTC+1, Matthew Fioravante
wrote:
>
>
>
> On Tuesday, February 24, 2015 at 9:39:41 AM UTC-5, Nicol Bolas wrote:
>>
>> On Monday, February 23, 2015 at 10:26:48 PM UTC-5, Matthew Fioravante
>> wrote:
>>>
>>> But it's very relevant to Foo. And since he's the owner and creator of
>>>> the array, he's the one who decides these things.
>>>>
>>>
>>> Yes that's right, but Foo doesn't have to advertise the fact unless
>>> asked for it. Which data is or is not managed may be a part of the Foo
>>> specification, but this information is not necessary for clients requesting
>>> a const view over the data. The fact that its managed by unique_ptr and not
>>> some other unique ownership mechanism is a pure implementation detail which
>>> should not be leaked to clients.
>>>
>>> By returning different types, we make it more difficult to write generic
>>> code without templates because we have this artificial dependency leaking
>>> all over the place. Even if foo does manage the resources referred to by
>>> getA(), the resource management may be performed using another data
>>> structure other than the array getA() references. If getA() could return
>>> array_view<T*>, we would have better encapsulation and freedom for the
>>> implementation of Foo.
>>>
>>
>> Foo wouldn't be free to use an internal implementation that wasn't
>> magically aliasable to a C-array of T. For example, it couldn't suddenly
>> decide that it needs shared ownership.
>>
>> If your consuming code was *fully* generic (ie: templates), then Foo
>> would *truly* be free to implement whatever it wanted.
>>
>>
>>> For all intents and purposes, your problem is the lack of modules in
>>>> C++. Here's what I mean.
>>>>
>>>> What you really want to do is give people a non-modifiable view of your
>>>> stored data. Your users won't care what specific types you may wrap your
>>>> stored data in, so long as they obey certain basic principles (ie: the
>>>> expectations of a pointer to T).
>>>>
>>>> The "correct" way to handle this is with templates. That is, code that
>>>> wants to consume your array_view would be a template, on the array view's
>>>> type (or the template type could be more general, a non-modifiable range of
>>>> pointer-to-T-like objects. Whatever). The problem is that now, all your
>>>> consuming code needs to live in header files. As much any code that just
>>>> passes your stuff along to others. Templates are rather viral like that.
>>>>
>>>> If you had modules, you wouldn't have to care. You'd just return an
>>>> array_view<unique_ptr<T>>, and those who wanted to consume it would be a
>>>> template that takes an appropriate range. Nobody would be subjected to the
>>>> details of your memory management (unless they deliberately choose to be).
>>>> And thanks to modules, they wouldn't be subjected to the horrible
>>>> compile-times that come along with doing all this (which is the #1 reason
>>>> why people avoid doing it today. #2 is the lack of concepts).
>>>>
>>>> Basically, this would be a solved problem if compile-time wasn't an
>>>> issue.
>>>>
>>>
>>> I haven't studied the latest work in modules yet. If I understand
>>> correctly, you're saying with modules basically everything can be a
>>> template and whether or not the range iterates over unique_ptr<T> or T* is
>>> irrelevant because it will just flow though the type system via type
>>> deduction like magic.
>>>
>>> This works fine until you need to pass the thing to a third party
>>> library which views a pointer by taking T* by reference.
>>>
>>
>> Yes, that happens. But how is that any different from *any* interface
>> with a third party library? There are always going to be libraries that use
>> something odd in their interfaces, that requires translation. What if
>> you're trying to stick that array into a Lua table or a Python array? You
>> need some form of translation.
>>
>> You would have this exact problem if 'Foo' stopped using a contiguous,
>> alias-able array. Isn't that the whole point? To not have third-party
>> libraries place arbitrary restrictions on your data structures (like "you
>> must use a contiguous array of pointers to some type")?
>>
>>
>>> It also burdens all of your code with more template syntax when it could
>>> just be simple function calls. The more meta-programming you add to your
>>> code, the more complex it becomes and the more time you have to spend
>>> making things generic.
>>>
>>
>> That's the point of concepts; it makes "template syntax" not be a
>> "burden". The point of modules is to make using "more template syntax"
>> practical.
>>
>> So my original point stands. It's not that you don't have a solution in
>> C++. It's that the C++ solution has these burdens on it that shouldn't be
>> there. Once those burdens are eased and/or eliminated, then your problem is
>> effectively solved.
>>
>>
>>>
>>>> This issue is making unique_ptr very cumbersome to use. Ideally I'd
>>>>> like to just be able to specify memory management once within the
>>>>> containing class data members and then pass around array_view<T*>
>>>>> everywhere externally, clients not knowing, caring, or recompiling whether
>>>>> the view points to a set of managed or unmanaged pointers.
>>>>>
>>>>
>>>> Well, that's just not going to happen. std::unique_ptr does not
>>>> (necessarily) have zero overhead. It all depends on the deleter.
>>>>
>>>
>>> If there is a custom or maybe even stateless deleter, I have yet to find
>>> a good reason (other than attaching debugging info) to not restrict
>>> implementations of unique_ptr to store only a T*. Adding a new type like
>>> trivial_ptr<T> seems less optimal than just reusing unique_ptr<T> with a
>>> stateless deleter. The alias() call can be conceptified to reject
>>> unique_ptr's, with stateful deleters.
>>>
>>>
>>>> Plus, that would require aliasing.
>>>>
>>>
>>> Ugly scary aliasing is the most efficient way to solve this problem. On
>>> modern machines, arrays are almost always the most efficient data structure
>>> to store data. array_view<T> brings an extremely flexible range library
>>> like solution for this most ubiquitous and efficient data layout, often
>>> without requiring templates at all.
>>>
>>> If you have an array of wrapper<T> stored in memory whose lifetime is
>>> managed by a stateless wrapper type, you need aliasing to efficiently
>>> retrieve a const view over the array of T.
>>>
>>
>> That would require aliasing. Which is *forbidden* in C++, regardless of
>> the size or representation of whatever wrapper you're using. Therefore,
>> what you're asking for is a *language change*, not merely a library
>> thing.
>>
>> And breaking strict aliasing just ain't gonna happen.
>>
>> You can either keep wanting something you're not going to get, or work
>> with what you actually have. I prefer option 2.
>>
>>
>>>
>>>
>>>>
>>>> The only solution here is a container that specifically handles memory
>>>> allocation, like Boost's ptr_vector. But I don't think this is a frequent
>>>> enough problem to have them standardize such a special use container.
>>>>
>>>
>>> I think the ptr_vector approach is not generic enough. Basically you
>>> have to create a copy of the std::vector<T> specification with some
>>> customized behavior only for pointers. Lifetime management is fully
>>> specified by T so a better solution is just to create a new stateless
>>> wrapper type to manage T* and be aliasable to to T*.
>>>
>>
>> Why is it "not generic enough"?
>>
>
> If we have ptr_vector, why not other kinds of ptr_ data structures? Are
> absolutely sure vector is the only data structure worth this specialization?
>
>
>
>> Sure, it specifically supports only unique ownership, but... so what?
>>
> What other kind of "lifetime management" are you going to be able to do
>> that is both stateless and (theoretically) aliasable to T*?
>>
>
> Any stateless memory allocator can be used in this context.
>
>
>>
>> ptr_vector is specifically *designed* to solve your exact problem. And
>> it doesn't require breaking strict aliasing (which again, is *not gonna
>> happen*). So why would you not use it?
>>
>
> If ptr_vector is the only possible solution then it will do because at
> least it solves the immediate problem.
>
--
---
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_1565_1636370600.1425130549821
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I think is possible to create `unique_container` that will=
warp around normal containers and have limited interface to maintain invar=
iants.<br>Simplest and dummiest implementation will look like:<br><div clas=
s=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-col=
or: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: =
break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">template</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #606;" class=3D"styled-by-prettify">Container</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">></span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">class</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> unique_container<br></span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br> </span><span style=3D"color: #606=
;" class=3D"styled-by-prettify">Container</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> c</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">public</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
</span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">template</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
"><</span><span style=3D"color: #008;" class=3D"styled-by-prettify">type=
name</span><span style=3D"color: #660;" class=3D"styled-by-prettify">...</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">></span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br> </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> emplace_back</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">...</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> t</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> c</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">push_back</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">new</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" clas=
s=3D"styled-by-prettify">Container</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">value_type</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">forward<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">T</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">>(</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">t</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">)...));</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> erase</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">size_t i</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">delete</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> c</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">[</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">i</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">];</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> c</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">erase</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">i</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">const</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-=
prettify">Container</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">&</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">get</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> returns c</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
> </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">~</span><span style=3D"color: #000;" class=3D"styled-by-prettify">uniq=
ue_container</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">for</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">auto</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">&</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> i </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
c</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;"=
class=3D"styled-by-prettify">delete</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> i</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">};</span></div></code></div><br><=
br><br>On Saturday, February 28, 2015 at 4:03:28 AM UTC+1, Matthew Fioravan=
te wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><br>=
<br>On Tuesday, February 24, 2015 at 9:39:41 AM UTC-5, Nicol Bolas wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Monday, February =
23, 2015 at 10:26:48 PM UTC-5, Matthew Fioravante wrote:<blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div><div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div>But it's very relevant to Foo. And sin=
ce he's the owner and creator of the array, he's the one who decides these =
things.<br></div></div></blockquote><div><br></div><div>Yes that's right, b=
ut Foo doesn't have to advertise the fact unless asked for it. Which data i=
s or is not managed may be a part of the Foo specification, but this inform=
ation is not necessary for clients requesting a const view over the data. T=
he fact that its managed by unique_ptr and not some other unique ownership =
mechanism is a pure implementation detail which should not be leaked to cli=
ents.</div><div><br></div><div>By returning different types, we make it mor=
e difficult to write generic code without templates because we have this ar=
tificial dependency leaking all over the place. Even if foo does manage the=
resources referred to by getA(), the resource management may be performed =
using another data structure other than the array getA() references. If get=
A() could return array_view<T*>, we would have better encapsulation a=
nd freedom for the implementation of Foo.</div></div></div></div></blockquo=
te><div><br>Foo wouldn't be free to use an internal implementation that was=
n't magically aliasable to a C-array of T. For example, it couldn't suddenl=
y decide that it needs shared ownership.<br><br>If your consuming code was =
<i>fully</i> generic (ie: templates), then Foo would <i>truly</i> be free t=
o implement whatever it wanted.<br> </div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div><div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><div>For all intents and purposes, your problem is the=
lack of modules in C++. Here's what I mean.<br><br>What you really want to=
do is give people a non-modifiable view of your stored data. Your users wo=
n't care what specific types you may wrap your stored data in, so long as t=
hey obey certain basic principles (ie: the expectations of a pointer to T).=
<br><br>The "correct" way to handle this is with templates. That is, code t=
hat wants to consume your array_view would be a template, on the array view=
's type (or the template type could be more general, a non-modifiable range=
of pointer-to-T-like objects. Whatever). The problem is that now, all your=
consuming code needs to live in header files. As much any code that just p=
asses your stuff along to others. Templates are rather viral like that.<br>=
<br>If you had modules, you wouldn't have to care. You'd just return an arr=
ay_view<unique_ptr<T>>, and those who wanted to consume it woul=
d be a template that takes an appropriate range. Nobody would be subjected =
to the details of your memory management (unless they deliberately choose t=
o be). And thanks to modules, they wouldn't be subjected to the horrible co=
mpile-times that come along with doing all this (which is the #1 reason why=
people avoid doing it today. #2 is the lack of concepts).<br><br>Basically=
, this would be a solved problem if compile-time wasn't an issue.<br></div>=
</div></blockquote><div><br></div><div>I haven't studied the latest work in=
modules yet. If I understand correctly, you're saying with modules basical=
ly everything can be a template and whether or not the range iterates over =
unique_ptr<T> or T* is irrelevant because it will just flow though th=
e type system via type deduction like magic.</div><div><br></div><div>This =
works fine until you need to pass the thing to a third party library which =
views a pointer by taking T* by reference.</div></div></div></div></blockqu=
ote><div><br>Yes, that happens. But how is that any different from <i>any</=
i> interface with a third party library? There are always going to be libra=
ries that use something odd in their interfaces, that requires translation.=
What if you're trying to stick that array into a Lua table or a Python arr=
ay? You need some form of translation.<br><br>You would have this exact pro=
blem if 'Foo' stopped using a contiguous, alias-able array. Isn't that the =
whole point? To not have third-party libraries place arbitrary restrictions=
on your data structures (like "you must use a contiguous array of pointers=
to some type")?<br> </div><blockquote class=3D"gmail_quote" style=3D"=
margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><di=
v dir=3D"ltr"><div><div><div>It also burdens all of your code with more tem=
plate syntax when it could just be simple function calls. The more meta-pro=
gramming you add to your code, the more complex it becomes and the more tim=
e you have to spend making things generic.</div></div></div></div></blockqu=
ote><div><br>That's the point of concepts; it makes "template syntax" not b=
e a "burden". The point of modules is to make using "more template syntax" =
practical.<br><br>So my original point stands. It's not that you don't have=
a solution in C++. It's that the C++ solution has these burdens on it that=
shouldn't be there. Once those burdens are eased and/or eliminated, then y=
our problem is effectively solved.<br> </div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div><div><blockquote class=3D"gmail_quote"=
style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr"><div><br></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr">This issue is making unique_ptr very cumbersome to use=
.. Ideally I'd like to just be able to specify memory management once within=
the containing class data members and then pass around array_view<T*>=
; everywhere externally, clients not knowing, caring, or recompiling whethe=
r the view points to a set of managed or unmanaged pointers.</div></blockqu=
ote><div><br>Well, that's just not going to happen. std::unique_ptr does no=
t (necessarily) have zero overhead. It all depends on the deleter. </div></=
div></blockquote><div><br>If there is a custom or maybe even stateless dele=
ter, I have yet to find a good reason (other than attaching debugging info)=
to not restrict implementations of unique_ptr to store only a T*. Adding a=
new type like trivial_ptr<T> seems less optimal than just reusing un=
ique_ptr<T> with a stateless deleter. The alias() call can be concept=
ified to reject unique_ptr's, with stateful deleters.</div><div> </div=
><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Plus, that w=
ould require aliasing.<br></div></div></blockquote><div><br></div><div>Ugly=
scary aliasing is the most efficient way to solve this problem. On modern =
machines, arrays are almost always the most efficient data structure to sto=
re data. array_view<T> brings an extremely flexible range library lik=
e solution for this most ubiquitous and efficient data layout, often withou=
t requiring templates at all.</div><div><br></div><div>If you have an array=
of wrapper<T> stored in memory whose lifetime is managed by a statel=
ess wrapper type, you need aliasing to efficiently retrieve a const view ov=
er the array of T.</div></div></div></div></blockquote><div><br>That would =
require aliasing. Which is <i>forbidden</i> in C++, regardless of the size =
or representation of whatever wrapper you're using. Therefore, what you're =
asking for is a <i>language change</i>, not merely a library thing.<br><br>=
And breaking strict aliasing just ain't gonna happen.<br><br>You can either=
keep wanting something you're not going to get, or work with what you actu=
ally have. I prefer option 2.<br> </div><blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div dir=3D"ltr"><div><div><div> </div><blockquote class=3D"=
gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid=
;padding-left:1ex"><div dir=3D"ltr"><div><br>The only solution here is a co=
ntainer that specifically handles memory allocation, like Boost's ptr_vecto=
r. But I don't think this is a frequent enough problem to have them standar=
dize such a special use container.<br></div></div></blockquote><div><br></d=
iv><span style=3D"font-size:13.1428575515747px">I think the ptr_vector appr=
oach is not generic enough. Basically you have to create a copy of the std:=
:vector<T> specification with some customized behavior only for point=
ers. Lifetime management is fully specified by T so a better solution is ju=
st to create a new stateless wrapper type to manage T* and be aliasable to =
to T*.</span></div></div></div></blockquote><div><br>Why is it "not generic=
enough"? </div></div></blockquote><div><br></div><div>If we have ptr_vecto=
r, why not other kinds of ptr_ data structures? Are absolutely sure vector =
is the only data structure worth this specialization?</div><div><br></div><=
div> </div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-=
left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><d=
iv>Sure, it specifically supports only unique ownership, but... so what?</d=
iv></div></blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><div>What other kind of "lifetime management" are you going to be able =
to do that is both stateless and (theoretically) aliasable to T*?<br></div>=
</div></blockquote><div><br></div><div>Any stateless memory allocator can b=
e used in this context.</div><div> </div><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding=
-left:1ex"><div dir=3D"ltr"><div><br>ptr_vector is specifically <i>designed=
</i> to solve your exact problem. And it doesn't require breaking strict al=
iasing (which again, is <i>not gonna happen</i>). So why would you not use =
it?<br></div></div></blockquote><div><br></div><div>If ptr_vector is the on=
ly possible solution then it will do because at least it solves the immedia=
te problem.</div></div></blockquote></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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_1565_1636370600.1425130549821--
------=_Part_1564_2079094591.1425130549821--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 28 Feb 2015 09:40:30 -0800 (PST)
Raw View
------=_Part_266_2070062207.1425145231010
Content-Type: multipart/alternative;
boundary="----=_Part_267_152948002.1425145231010"
------=_Part_267_152948002.1425145231010
Content-Type: text/plain; charset=UTF-8
On Friday, February 27, 2015 at 10:03:28 PM UTC-5, Matthew Fioravante wrote:
>
>
>
> On Tuesday, February 24, 2015 at 9:39:41 AM UTC-5, Nicol Bolas wrote:
>>
>> On Monday, February 23, 2015 at 10:26:48 PM UTC-5, Matthew Fioravante
>> wrote:
>>>
>>> But it's very relevant to Foo. And since he's the owner and creator of
>>>> the array, he's the one who decides these things.
>>>>
>>>
>>> Yes that's right, but Foo doesn't have to advertise the fact unless
>>> asked for it. Which data is or is not managed may be a part of the Foo
>>> specification, but this information is not necessary for clients requesting
>>> a const view over the data. The fact that its managed by unique_ptr and not
>>> some other unique ownership mechanism is a pure implementation detail which
>>> should not be leaked to clients.
>>>
>>> By returning different types, we make it more difficult to write generic
>>> code without templates because we have this artificial dependency leaking
>>> all over the place. Even if foo does manage the resources referred to by
>>> getA(), the resource management may be performed using another data
>>> structure other than the array getA() references. If getA() could return
>>> array_view<T*>, we would have better encapsulation and freedom for the
>>> implementation of Foo.
>>>
>>
>> Foo wouldn't be free to use an internal implementation that wasn't
>> magically aliasable to a C-array of T. For example, it couldn't suddenly
>> decide that it needs shared ownership.
>>
>> If your consuming code was *fully* generic (ie: templates), then Foo
>> would *truly* be free to implement whatever it wanted.
>>
>>
>>> For all intents and purposes, your problem is the lack of modules in
>>>> C++. Here's what I mean.
>>>>
>>>> What you really want to do is give people a non-modifiable view of your
>>>> stored data. Your users won't care what specific types you may wrap your
>>>> stored data in, so long as they obey certain basic principles (ie: the
>>>> expectations of a pointer to T).
>>>>
>>>> The "correct" way to handle this is with templates. That is, code that
>>>> wants to consume your array_view would be a template, on the array view's
>>>> type (or the template type could be more general, a non-modifiable range of
>>>> pointer-to-T-like objects. Whatever). The problem is that now, all your
>>>> consuming code needs to live in header files. As much any code that just
>>>> passes your stuff along to others. Templates are rather viral like that.
>>>>
>>>> If you had modules, you wouldn't have to care. You'd just return an
>>>> array_view<unique_ptr<T>>, and those who wanted to consume it would be a
>>>> template that takes an appropriate range. Nobody would be subjected to the
>>>> details of your memory management (unless they deliberately choose to be).
>>>> And thanks to modules, they wouldn't be subjected to the horrible
>>>> compile-times that come along with doing all this (which is the #1 reason
>>>> why people avoid doing it today. #2 is the lack of concepts).
>>>>
>>>> Basically, this would be a solved problem if compile-time wasn't an
>>>> issue.
>>>>
>>>
>>> I haven't studied the latest work in modules yet. If I understand
>>> correctly, you're saying with modules basically everything can be a
>>> template and whether or not the range iterates over unique_ptr<T> or T* is
>>> irrelevant because it will just flow though the type system via type
>>> deduction like magic.
>>>
>>> This works fine until you need to pass the thing to a third party
>>> library which views a pointer by taking T* by reference.
>>>
>>
>> Yes, that happens. But how is that any different from *any* interface
>> with a third party library? There are always going to be libraries that use
>> something odd in their interfaces, that requires translation. What if
>> you're trying to stick that array into a Lua table or a Python array? You
>> need some form of translation.
>>
>> You would have this exact problem if 'Foo' stopped using a contiguous,
>> alias-able array. Isn't that the whole point? To not have third-party
>> libraries place arbitrary restrictions on your data structures (like "you
>> must use a contiguous array of pointers to some type")?
>>
>>
>>> It also burdens all of your code with more template syntax when it could
>>> just be simple function calls. The more meta-programming you add to your
>>> code, the more complex it becomes and the more time you have to spend
>>> making things generic.
>>>
>>
>> That's the point of concepts; it makes "template syntax" not be a
>> "burden". The point of modules is to make using "more template syntax"
>> practical.
>>
>> So my original point stands. It's not that you don't have a solution in
>> C++. It's that the C++ solution has these burdens on it that shouldn't be
>> there. Once those burdens are eased and/or eliminated, then your problem is
>> effectively solved.
>>
>>
>>>
>>>> This issue is making unique_ptr very cumbersome to use. Ideally I'd
>>>>> like to just be able to specify memory management once within the
>>>>> containing class data members and then pass around array_view<T*>
>>>>> everywhere externally, clients not knowing, caring, or recompiling whether
>>>>> the view points to a set of managed or unmanaged pointers.
>>>>>
>>>>
>>>> Well, that's just not going to happen. std::unique_ptr does not
>>>> (necessarily) have zero overhead. It all depends on the deleter.
>>>>
>>>
>>> If there is a custom or maybe even stateless deleter, I have yet to find
>>> a good reason (other than attaching debugging info) to not restrict
>>> implementations of unique_ptr to store only a T*. Adding a new type like
>>> trivial_ptr<T> seems less optimal than just reusing unique_ptr<T> with a
>>> stateless deleter. The alias() call can be conceptified to reject
>>> unique_ptr's, with stateful deleters.
>>>
>>>
>>>> Plus, that would require aliasing.
>>>>
>>>
>>> Ugly scary aliasing is the most efficient way to solve this problem. On
>>> modern machines, arrays are almost always the most efficient data structure
>>> to store data. array_view<T> brings an extremely flexible range library
>>> like solution for this most ubiquitous and efficient data layout, often
>>> without requiring templates at all.
>>>
>>> If you have an array of wrapper<T> stored in memory whose lifetime is
>>> managed by a stateless wrapper type, you need aliasing to efficiently
>>> retrieve a const view over the array of T.
>>>
>>
>> That would require aliasing. Which is *forbidden* in C++, regardless of
>> the size or representation of whatever wrapper you're using. Therefore,
>> what you're asking for is a *language change*, not merely a library
>> thing.
>>
>> And breaking strict aliasing just ain't gonna happen.
>>
>> You can either keep wanting something you're not going to get, or work
>> with what you actually have. I prefer option 2.
>>
>>
>>>
>>>
>>>>
>>>> The only solution here is a container that specifically handles memory
>>>> allocation, like Boost's ptr_vector. But I don't think this is a frequent
>>>> enough problem to have them standardize such a special use container.
>>>>
>>>
>>> I think the ptr_vector approach is not generic enough. Basically you
>>> have to create a copy of the std::vector<T> specification with some
>>> customized behavior only for pointers. Lifetime management is fully
>>> specified by T so a better solution is just to create a new stateless
>>> wrapper type to manage T* and be aliasable to to T*.
>>>
>>
>> Why is it "not generic enough"?
>>
>
> If we have ptr_vector, why not other kinds of ptr_ data structures? Are
> absolutely sure vector is the only data structure worth this specialization?
>
Because they don't make sense. The only reason ptr_vector is even needed is
to allow aliasing of what is to effectively allow
std::vector<unique_ptr<T>> to be aliased with T*. If you need a
std::list<T*> with some particular containment strategy, just wrap that
strategy in a smart pointer and make a std::list<smart_ptr<T>>.
>
>> Sure, it specifically supports only unique ownership, but... so what?
>>
> What other kind of "lifetime management" are you going to be able to do
>> that is both stateless and (theoretically) aliasable to T*?
>>
>
> Any stateless memory allocator can be used in this context.
>
I'll assume you said, "any memory allocator who's state is not stored in
the smart pointer". Since that allows for intrusive smart pointer
emulation. They do have state; it's just that their state isn't stored in
the smart pointer. It's stored in the T object.
So yes, I could see some kind of "deleter" object being used for a
standardized ptr_vector, which would provide an interface for intrusive
state. On acquiring a pointer, it would call an acquire method, and on
releasing it, it would call a release method. So if you're using shared
ownership via intrusive data, then your acquire and release methods would
cover that.
--
---
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_267_152948002.1425145231010
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Friday, February 27, 2015 at 10:03:28 PM UTC-5,=
Matthew Fioravante wrote:<blockquote class=3D"gmail_quote" style=3D"margin=
: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div=
dir=3D"ltr"><br><br>On Tuesday, February 24, 2015 at 9:39:41 AM UTC-5, Nic=
ol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On =
Monday, February 23, 2015 at 10:26:48 PM UTC-5, Matthew Fioravante wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
#ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>But it's very relevant =
to Foo. And since he's the owner and creator of the array, he's the one who=
decides these things.<br></div></div></blockquote><div><br></div><div>Yes =
that's right, but Foo doesn't have to advertise the fact unless asked for i=
t. Which data is or is not managed may be a part of the Foo specification, =
but this information is not necessary for clients requesting a const view o=
ver the data. The fact that its managed by unique_ptr and not some other un=
ique ownership mechanism is a pure implementation detail which should not b=
e leaked to clients.</div><div><br></div><div>By returning different types,=
we make it more difficult to write generic code without templates because =
we have this artificial dependency leaking all over the place. Even if foo =
does manage the resources referred to by getA(), the resource management ma=
y be performed using another data structure other than the array getA() ref=
erences. If getA() could return array_view<T*>, we would have better =
encapsulation and freedom for the implementation of Foo.</div></div></div><=
/div></blockquote><div><br>Foo wouldn't be free to use an internal implemen=
tation that wasn't magically aliasable to a C-array of T. For example, it c=
ouldn't suddenly decide that it needs shared ownership.<br><br>If your cons=
uming code was <i>fully</i> generic (ie: templates), then Foo would <i>trul=
y</i> be free to implement whatever it wanted.<br> </div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr"><div><div><blockquote class=3D"=
gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid=
;padding-left:1ex"><div dir=3D"ltr"><div>For all intents and purposes, your=
problem is the lack of modules in C++. Here's what I mean.<br><br>What you=
really want to do is give people a non-modifiable view of your stored data=
.. Your users won't care what specific types you may wrap your stored data i=
n, so long as they obey certain basic principles (ie: the expectations of a=
pointer to T).<br><br>The "correct" way to handle this is with templates. =
That is, code that wants to consume your array_view would be a template, on=
the array view's type (or the template type could be more general, a non-m=
odifiable range of pointer-to-T-like objects. Whatever). The problem is tha=
t now, all your consuming code needs to live in header files. As much any c=
ode that just passes your stuff along to others. Templates are rather viral=
like that.<br><br>If you had modules, you wouldn't have to care. You'd jus=
t return an array_view<unique_ptr<T>>, and those who wanted to =
consume it would be a template that takes an appropriate range. Nobody woul=
d be subjected to the details of your memory management (unless they delibe=
rately choose to be). And thanks to modules, they wouldn't be subjected to =
the horrible compile-times that come along with doing all this (which is th=
e #1 reason why people avoid doing it today. #2 is the lack of concepts).<b=
r><br>Basically, this would be a solved problem if compile-time wasn't an i=
ssue.<br></div></div></blockquote><div><br></div><div>I haven't studied the=
latest work in modules yet. If I understand correctly, you're saying with =
modules basically everything can be a template and whether or not the range=
iterates over unique_ptr<T> or T* is irrelevant because it will just=
flow though the type system via type deduction like magic.</div><div><br><=
/div><div>This works fine until you need to pass the thing to a third party=
library which views a pointer by taking T* by reference.</div></div></div>=
</div></blockquote><div><br>Yes, that happens. But how is that any differen=
t from <i>any</i> interface with a third party library? There are always go=
ing to be libraries that use something odd in their interfaces, that requir=
es translation. What if you're trying to stick that array into a Lua table =
or a Python array? You need some form of translation.<br><br>You would have=
this exact problem if 'Foo' stopped using a contiguous, alias-able array. =
Isn't that the whole point? To not have third-party libraries place arbitra=
ry restrictions on your data structures (like "you must use a contiguous ar=
ray of pointers to some type")?<br> </div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div><div><div>It also burdens all of your cod=
e with more template syntax when it could just be simple function calls. Th=
e more meta-programming you add to your code, the more complex it becomes a=
nd the more time you have to spend making things generic.</div></div></div>=
</div></blockquote><div><br>That's the point of concepts; it makes "templat=
e syntax" not be a "burden". The point of modules is to make using "more te=
mplate syntax" practical.<br><br>So my original point stands. It's not that=
you don't have a solution in C++. It's that the C++ solution has these bur=
dens on it that shouldn't be there. Once those burdens are eased and/or eli=
minated, then your problem is effectively solved.<br> </div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
#ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div><br></div><blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr">This issue is making unique_ptr very c=
umbersome to use. Ideally I'd like to just be able to specify memory manage=
ment once within the containing class data members and then pass around arr=
ay_view<T*> everywhere externally, clients not knowing, caring, or re=
compiling whether the view points to a set of managed or unmanaged pointers=
..</div></blockquote><div><br>Well, that's just not going to happen. std::un=
ique_ptr does not (necessarily) have zero overhead. It all depends on the d=
eleter. </div></div></blockquote><div><br>If there is a custom or maybe eve=
n stateless deleter, I have yet to find a good reason (other than attaching=
debugging info) to not restrict implementations of unique_ptr to store onl=
y a T*. Adding a new type like trivial_ptr<T> seems less optimal than=
just reusing unique_ptr<T> with a stateless deleter. The alias() cal=
l can be conceptified to reject unique_ptr's, with stateful deleters.</div>=
<div> </div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin=
-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><=
div>Plus, that would require aliasing.<br></div></div></blockquote><div><br=
></div><div>Ugly scary aliasing is the most efficient way to solve this pro=
blem. On modern machines, arrays are almost always the most efficient data =
structure to store data. array_view<T> brings an extremely flexible r=
ange library like solution for this most ubiquitous and efficient data layo=
ut, often without requiring templates at all.</div><div><br></div><div>If y=
ou have an array of wrapper<T> stored in memory whose lifetime is man=
aged by a stateless wrapper type, you need aliasing to efficiently retrieve=
a const view over the array of T.</div></div></div></div></blockquote><div=
><br>That would require aliasing. Which is <i>forbidden</i> in C++, regardl=
ess of the size or representation of whatever wrapper you're using. Therefo=
re, what you're asking for is a <i>language change</i>, not merely a librar=
y thing.<br><br>And breaking strict aliasing just ain't gonna happen.<br><b=
r>You can either keep wanting something you're not going to get, or work wi=
th what you actually have. I prefer option 2.<br> </div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr"><div><div><div> </div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br>The only solut=
ion here is a container that specifically handles memory allocation, like B=
oost's ptr_vector. But I don't think this is a frequent enough problem to h=
ave them standardize such a special use container.<br></div></div></blockqu=
ote><div><br></div><span style=3D"font-size:13.1428575515747px">I think the=
ptr_vector approach is not generic enough. Basically you have to create a =
copy of the std::vector<T> specification with some customized behavio=
r only for pointers. Lifetime management is fully specified by T so a bette=
r solution is just to create a new stateless wrapper type to manage T* and =
be aliasable to to T*.</span></div></div></div></blockquote><div><br>Why is=
it "not generic enough"? </div></div></blockquote><div><br></div><div>If w=
e have ptr_vector, why not other kinds of ptr_ data structures? Are absolut=
ely sure vector is the only data structure worth this specialization?</div>=
</div></blockquote><div><br>Because they don't make sense. The only reason =
ptr_vector is even needed is to allow aliasing of what is to effectively al=
low std::vector<unique_ptr<T>> to be aliased with T*. If you ne=
ed a std::list<T*> with some particular containment strategy, just wr=
ap that strategy in a smart pointer and make a std::list<smart_ptr<T&=
gt;>.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div> </div><blockquote class=3D"gmail_quote" style=3D"margin=
:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div>Sure, it specifically supports only unique ownership, but... =
so what?</div></div></blockquote><blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><div>What other kind of "lifetime management" are you going =
to be able to do that is both stateless and (theoretically) aliasable to T*=
?<br></div></div></blockquote><div><br></div><div>Any stateless memory allo=
cator can be used in this context.</div></div></blockquote><div><br>I'll as=
sume you said, "any memory allocator who's state is not stored in the smart=
pointer". Since that allows for intrusive smart pointer emulation. They do=
have state; it's just that their state isn't stored in the smart pointer. =
It's stored in the T object.<br><br>So yes, I could see some kind of "delet=
er" object being used for a standardized ptr_vector, which would provide an=
interface for intrusive state. On acquiring a pointer, it would call an ac=
quire method, and on releasing it, it would call a release method. So if yo=
u're using shared ownership via intrusive data, then your acquire and relea=
se methods would cover that.<br></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" 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_267_152948002.1425145231010--
------=_Part_266_2070062207.1425145231010--
.