Topic: std::optional -- take 2


Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Wed, 19 Dec 2012 03:20:46 -0800 (PST)
Raw View
------=_Part_429_25188387.1355916046092
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Op donderdag 6 september 2012 22:35:30 UTC+2 schreef Andrzej Krzemie=C5=84s=
ki=20
het volgende:

> The only thing we are still making our mind on is the signature  and=20
> variants of function get_value_or (what combination of references it shou=
ld=20
> provide, and whether it should or not return by value).
>
> Hi,

> The function also works for optional references. In this case the=20
returned value is created from the referred object; a copy is returned. It=
=20
has been argued that the function should return by constant reference=20
rather than value, which would avoid copy overhead in certain situations:=
=20

> However, the benefit of the function get_value_or is only visible when=20
the optional object is provided as a temporary (without the name);=20
otherwise, a ternary operator is equally useful:

> Also, returning by reference would be likely to render a dangling=20
reference, in case the optional object is disengaged, because the second=20
argument is typically a temporary:

What if the arguments can't (or shouldn't) be copied?

class C : noncopyable;

C default;
C* a =3D ...;
C& b =3D get_value_or(a, default);
b.do_something();

--=20




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

Op donderdag 6 september 2012 22:35:30 UTC+2 schreef Andrzej Krzemie=C5=84s=
ki het volgende:<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">The only t=
hing we are still making our mind on is the signature&nbsp; and variants of=
 function get_value_or (what combination of references it should provide, a=
nd whether it should or not return by value).<br><br></blockquote><div>Hi,<=
/div><div><br></div><div><span style=3D"color: rgb(0, 0, 0); font-family: '=
Times New Roman'; font-size: medium;">&gt; The function also works for opti=
onal references. In this case the returned value is created from the referr=
ed object; a copy is returned. It has been argued that the function should =
return by constant reference rather than value, which would avoid copy over=
head in certain situations:</span>&nbsp;</div><div><br></div><div>&gt;&nbsp=
;<span style=3D"color: rgb(0, 0, 0); font-family: 'Times New Roman'; font-s=
ize: medium;">However, the benefit of the function&nbsp;</span><code style=
=3D"color: rgb(0, 0, 0);">get_value_or</code><span style=3D"color: rgb(0, 0=
, 0); font-family: 'Times New Roman'; font-size: medium;">&nbsp;is only vis=
ible when the optional object is provided as a temporary (without the name)=
; otherwise, a ternary operator is equally useful:</span></div><div><span s=
tyle=3D"color: rgb(0, 0, 0); font-family: 'Times New Roman'; font-size: med=
ium;"><br></span></div><div><span style=3D"color: rgb(0, 0, 0); font-family=
: 'Times New Roman'; font-size: medium;">&gt;&nbsp;</span><span style=3D"co=
lor: rgb(0, 0, 0); font-family: 'Times New Roman'; font-size: medium;">Also=
, returning by reference would be likely to render a dangling reference, in=
 case the optional object is disengaged, because the second argument is typ=
ically a temporary:</span></div><div><span style=3D"color: rgb(0, 0, 0); fo=
nt-family: 'Times New Roman'; font-size: medium;"><br></span></div><div><sp=
an style=3D"color: rgb(0, 0, 0); font-family: 'Times New Roman'; font-size:=
 medium;">What if the arguments can't (or shouldn't) be copied?</span></div=
><div><span style=3D"color: rgb(0, 0, 0); font-family: 'Times New Roman'; f=
ont-size: medium;"><br></span></div><div><span style=3D"color: rgb(0, 0, 0)=
; font-family: 'Times New Roman'; font-size: medium;">class C : noncopyable=
;</span></div><div><span style=3D"color: rgb(0, 0, 0); font-family: 'Times =
New Roman'; font-size: medium;"><br></span></div><div><span style=3D"color:=
 rgb(0, 0, 0); font-family: 'Times New Roman'; font-size: medium;">C defaul=
t;</span></div><div><span style=3D"color: rgb(0, 0, 0); font-family: 'Times=
 New Roman'; font-size: medium;">C* a =3D ...;</span></div><div><span style=
=3D"color: rgb(0, 0, 0); font-family: 'Times New Roman'; font-size: medium;=
">C&amp; b =3D get_value_or(a, default);</span></div><div><span style=3D"co=
lor: rgb(0, 0, 0); font-family: 'Times New Roman'; font-size: medium;">b.do=
_something();</span></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_429_25188387.1355916046092--

.


Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Wed, 19 Dec 2012 03:24:26 -0800 (PST)
Raw View
------=_Part_67_11024690.1355916266983
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Op woensdag 19 december 2012 12:20:46 UTC+1 schreef Olaf van der Spek het=
=20
volgende:

> Op donderdag 6 september 2012 22:35:30 UTC+2 schreef Andrzej Krzemie=C5=
=84ski=20
> het volgende:
>
>> The only thing we are still making our mind on is the signature  and=20
>> variants of function get_value_or (what combination of references it sho=
uld=20
>> provide, and whether it should or not return by value).
>>
>> Hi,
>
> > The function also works for optional references. In this case the=20
> returned value is created from the referred object; a copy is returned. I=
t=20
> has been argued that the function should return by constant reference=20
> rather than value, which would avoid copy overhead in certain situations:=
=20
>
> > However, the benefit of the function get_value_or is only visible when=
=20
> the optional object is provided as a temporary (without the name);=20
> otherwise, a ternary operator is equally useful:
>
> > Also, returning by reference would be likely to render a dangling=20
> reference, in case the optional object is disengaged, because the second=
=20
> argument is typically a temporary:
>
> What if the arguments can't (or shouldn't) be copied?
>
> class C : noncopyable;
>
> C default;
> C* a =3D ...;
> C& b =3D get_value_or(a, default);
> b.do_something();
>

Bad example, a isn't a temporary.
=20
C* a();

C& b =3D get_value_or(a(), default);

--=20




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

Op woensdag 19 december 2012 12:20:46 UTC+1 schreef Olaf van der Spek het v=
olgende:<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Op donderdag 6 sep=
tember 2012 22:35:30 UTC+2 schreef Andrzej Krzemie=C5=84ski het volgende:<b=
r><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex">The only thing we are still makin=
g our mind on is the signature&nbsp; and variants of function get_value_or =
(what combination of references it should provide, and whether it should or=
 not return by value).<br><br></blockquote><div>Hi,</div><div><br></div><di=
v><span style=3D"color:rgb(0,0,0);font-family:'Times New Roman';font-size:m=
edium">&gt; The function also works for optional references. In this case t=
he returned value is created from the referred object; a copy is returned. =
It has been argued that the function should return by constant reference ra=
ther than value, which would avoid copy overhead in certain situations:</sp=
an>&nbsp;</div><div><br></div><div>&gt;&nbsp;<span style=3D"color:rgb(0,0,0=
);font-family:'Times New Roman';font-size:medium">However, the benefit of t=
he function&nbsp;</span><code style=3D"color:rgb(0,0,0)">get_value_or</code=
><span style=3D"color:rgb(0,0,0);font-family:'Times New Roman';font-size:me=
dium">&nbsp;is only visible when the optional object is provided as a tempo=
rary (without the name); otherwise, a ternary operator is equally useful:</=
span></div><div><span style=3D"color:rgb(0,0,0);font-family:'Times New Roma=
n';font-size:medium"><br></span></div><div><span style=3D"color:rgb(0,0,0);=
font-family:'Times New Roman';font-size:medium">&gt;&nbsp;</span><span styl=
e=3D"color:rgb(0,0,0);font-family:'Times New Roman';font-size:medium">Also,=
 returning by reference would be likely to render a dangling reference, in =
case the optional object is disengaged, because the second argument is typi=
cally a temporary:</span></div><div><span style=3D"color:rgb(0,0,0);font-fa=
mily:'Times New Roman';font-size:medium"><br></span></div><div><span style=
=3D"color:rgb(0,0,0);font-family:'Times New Roman';font-size:medium">What i=
f the arguments can't (or shouldn't) be copied?</span></div><div><span styl=
e=3D"color:rgb(0,0,0);font-family:'Times New Roman';font-size:medium"><br><=
/span></div><div><span style=3D"color:rgb(0,0,0);font-family:'Times New Rom=
an';font-size:medium">class C : noncopyable;</span></div><div><span style=
=3D"color:rgb(0,0,0);font-family:'Times New Roman';font-size:medium"><br></=
span></div><div><span style=3D"color:rgb(0,0,0);font-family:'Times New Roma=
n';font-size:medium">C default;</span></div><div><span style=3D"color:rgb(0=
,0,0);font-family:'Times New Roman';font-size:medium">C* a =3D ...;</span><=
/div><div><span style=3D"color:rgb(0,0,0);font-family:'Times New Roman';fon=
t-size:medium">C&amp; b =3D get_value_or(a, default);</span></div><div><spa=
n style=3D"color:rgb(0,0,0);font-family:'Times New Roman';font-size:medium"=
>b.do_something();</span></div></blockquote><div><br></div><div>Bad example=
, a isn't a temporary.</div><div>&nbsp;</div><div>C* a();</div><div><br></d=
iv><div><span style=3D"color: rgb(0, 0, 0); font-family: 'Times New Roman';=
 font-size: medium;">C&amp; b =3D get_value_or(a(), default);</span><br></d=
iv>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_67_11024690.1355916266983--

.


Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Wed, 19 Dec 2012 03:50:33 -0800 (PST)
Raw View
------=_Part_408_3103951.1355917833703
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable



W dniu =B6roda, 19 grudnia 2012 12:24:26 UTC+1 u=BFytkownik Olaf van der Sp=
ek=20
napisa=B3:
>
> Op woensdag 19 december 2012 12:20:46 UTC+1 schreef Olaf van der Spek het=
=20
> volgende:
>
>> Op donderdag 6 september 2012 22:35:30 UTC+2 schreef Andrzej Krzemie=F1s=
ki=20
>> het volgende:
>>
>>> The only thing we are still making our mind on is the signature  and=20
>>> variants of function get_value_or (what combination of references it sh=
ould=20
>>> provide, and whether it should or not return by value).
>>>
>>> Hi,
>>
>> > The function also works for optional references. In this case the=20
>> returned value is created from the referred object; a copy is returned. =
It=20
>> has been argued that the function should return by constant reference=20
>> rather than value, which would avoid copy overhead in certain situations=
:
>> =20
>>
>> > However, the benefit of the function get_value_or is only visible when=
=20
>> the optional object is provided as a temporary (without the name);=20
>> otherwise, a ternary operator is equally useful:
>>
>> > Also, returning by reference would be likely to render a dangling=20
>> reference, in case the optional object is disengaged, because the second=
=20
>> argument is typically a temporary:
>>
>> What if the arguments can't (or shouldn't) be copied?
>>
>> class C : noncopyable;
>>
>> C default;
>> C* a =3D ...;
>> C& b =3D get_value_or(a, default);
>> b.do_something();
>>
>
> Bad example, a isn't a temporary.
> =20
> C* a();
>
> C& b =3D get_value_or(a(), default);
>

I think something is wrong with this example: a() does not return an=20
optional. But to answer your initial question "What if the arguments can't=
=20
(or shouldn't) be copied?" -- if the semantics of get_value_or do not suit=
=20
your needs you should resort to other tools: ternary operator or some such.

Regards,
&rzej

--=20




------=_Part_408_3103951.1355917833703
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

<br><br>W dniu =B6roda, 19 grudnia 2012 12:24:26 UTC+1 u=BFytkownik Olaf va=
n der Spek napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Op woensd=
ag 19 december 2012 12:20:46 UTC+1 schreef Olaf van der Spek het volgende:<=
br><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex">Op donderdag 6 september 2012 22=
:35:30 UTC+2 schreef Andrzej Krzemie=F1ski het volgende:<br><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc=
 solid;padding-left:1ex">The only thing we are still making our mind on is =
the signature&nbsp; and variants of function get_value_or (what combination=
 of references it should provide, and whether it should or not return by va=
lue).<br><br></blockquote><div>Hi,</div><div><br></div><div><span style=3D"=
color:rgb(0,0,0);font-family:'Times New Roman';font-size:medium">&gt; The f=
unction also works for optional references. In this case the returned value=
 is created from the referred object; a copy is returned. It has been argue=
d that the function should return by constant reference rather than value, =
which would avoid copy overhead in certain situations:</span>&nbsp;</div><d=
iv><br></div><div>&gt;&nbsp;<span style=3D"color:rgb(0,0,0);font-family:'Ti=
mes New Roman';font-size:medium">However, the benefit of the function&nbsp;=
</span><code style=3D"color:rgb(0,0,0)">get_value_or</code><span style=3D"c=
olor:rgb(0,0,0);font-family:'Times New Roman';font-size:medium">&nbsp;is on=
ly visible when the optional object is provided as a temporary (without the=
 name); otherwise, a ternary operator is equally useful:</span></div><div><=
span style=3D"color:rgb(0,0,0);font-family:'Times New Roman';font-size:medi=
um"><br></span></div><div><span style=3D"color:rgb(0,0,0);font-family:'Time=
s New Roman';font-size:medium">&gt;&nbsp;</span><span style=3D"color:rgb(0,=
0,0);font-family:'Times New Roman';font-size:medium">Also, returning by ref=
erence would be likely to render a dangling reference, in case the optional=
 object is disengaged, because the second argument is typically a temporary=
:</span></div><div><span style=3D"color:rgb(0,0,0);font-family:'Times New R=
oman';font-size:medium"><br></span></div><div><span style=3D"color:rgb(0,0,=
0);font-family:'Times New Roman';font-size:medium">What if the arguments ca=
n't (or shouldn't) be copied?</span></div><div><span style=3D"color:rgb(0,0=
,0);font-family:'Times New Roman';font-size:medium"><br></span></div><div><=
span style=3D"color:rgb(0,0,0);font-family:'Times New Roman';font-size:medi=
um">class C : noncopyable;</span></div><div><span style=3D"color:rgb(0,0,0)=
;font-family:'Times New Roman';font-size:medium"><br></span></div><div><spa=
n style=3D"color:rgb(0,0,0);font-family:'Times New Roman';font-size:medium"=
>C default;</span></div><div><span style=3D"color:rgb(0,0,0);font-family:'T=
imes New Roman';font-size:medium">C* a =3D ...;</span></div><div><span styl=
e=3D"color:rgb(0,0,0);font-family:'Times New Roman';font-size:medium">C&amp=
; b =3D get_value_or(a, default);</span></div><div><span style=3D"color:rgb=
(0,0,0);font-family:'Times New Roman';font-size:medium">b.do_something();</=
span></div></blockquote><div><br></div><div>Bad example, a isn't a temporar=
y.</div><div>&nbsp;</div><div>C* a();</div><div><br></div><div><span style=
=3D"color:rgb(0,0,0);font-family:'Times New Roman';font-size:medium">C&amp;=
 b =3D get_value_or(a(), default);</span><br></div></blockquote><div><br>I =
think something is wrong with this example: a() does not return an optional=
.. But to answer your initial question "What if the arguments can't (or shou=
ldn't) be copied?" -- if the semantics of get_value_or do not suit your nee=
ds you should resort to other tools: ternary operator or some such.<br><br>=
Regards,<br>&amp;rzej<br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_408_3103951.1355917833703--

.


Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Wed, 19 Dec 2012 12:58:41 +0100
Raw View
On Wed, Dec 19, 2012 at 12:50 PM, Andrzej Krzemie=C5=84ski
<akrzemi1@gmail.com> wrote:
>>> What if the arguments can't (or shouldn't) be copied?
>>>
>>> class C : noncopyable;
>>>
>>> C default;
>>> C* a =3D ...;
>>> C& b =3D get_value_or(a, default);
>>> b.do_something();
>>
>>
>> Bad example, a isn't a temporary.
>>
>> C* a();
>>
>> C& b =3D get_value_or(a(), default);
>
>
> I think something is wrong with this example: a() does not return an
> optional. But to answer your initial question "What if the arguments can'=
t
> (or shouldn't) be copied?" -- if the semantics of get_value_or do not sui=
t
> your needs you should resort to other tools: ternary operator or some suc=
h.

I assumed get_value_or would support pointers too ("This function
template could be equally well be applied to any type satysfying the
requirements of NullableProxy."), but I guess it doesn't. So it's not
as generic as it could be.
A ternary operator isn't suitable if one or both of the arguments are unnam=
ed.

--=20
Olaf

--=20




.


Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Sat, 22 Dec 2012 06:10:06 -0800 (PST)
Raw View
------=_Part_346_19835069.1356185406401
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable



W dniu =B6roda, 19 grudnia 2012 12:58:41 UTC+1 u=BFytkownik Olaf van der Sp=
ek=20
napisa=B3:
>
> On Wed, Dec 19, 2012 at 12:50 PM, Andrzej Krzemie=F1ski=20
> <akrz...@gmail.com <javascript:>> wrote:=20
> >>> What if the arguments can't (or shouldn't) be copied?=20
> >>>=20
> >>> class C : noncopyable;=20
> >>>=20
> >>> C default;=20
> >>> C* a =3D ...;=20
> >>> C& b =3D get_value_or(a, default);=20
> >>> b.do_something();=20
> >>=20
> >>=20
> >> Bad example, a isn't a temporary.=20
> >>=20
> >> C* a();=20
> >>=20
> >> C& b =3D get_value_or(a(), default);=20
> >=20
> >=20
> > I think something is wrong with this example: a() does not return an=20
> > optional. But to answer your initial question "What if the arguments=20
> can't=20
> > (or shouldn't) be copied?" -- if the semantics of get_value_or do not=
=20
> suit=20
> > your needs you should resort to other tools: ternary operator or some=
=20
> such.=20
>
> I assumed get_value_or would support pointers too ("This function=20
> template could be equally well be applied to any type satysfying the=20
> requirements of NullableProxy."), but I guess it doesn't. So it's not=20
> as generic as it could be.=20
> A ternary operator isn't suitable if one or both of the arguments are=20
> unnamed.=20
>

OK, my reply was too scarce. The goal of this function was to assist with=
=20
the most common use case, where the T in optional is int or std::string.

optional<int> getCount();
int ans =3D get_value_or(getCount(), 0);

In these cases the function works fine, although the notation would be=20
cleaner if it was a member function.=20

int ans =3D getCount().get_value_or(0);

We do not expect of it to be a general purpose tool for every possible=20
usage. For some usages you will have to resort to other means.

We also considered generalizing it to any NullableProxy, but it comes with=
=20
certain difficulties. Because optional<T> owns the T we can optimize our=20
function for rvalue references: we can move the T. This would be disastrous=
=20
for rvalues of pointer type.

Also, you mentioned earlier that get_value_or doesn't work for non-Novable=
=20
types. One of the reasons for that is that is that we wanted to prevent=20
dangling references. The other reason is that it is difficult to imagine=20
how you would like to use get_value_or with T's that are not movable. Hence=
=20
the part "value" in function name. Do you know of a real-life use case for=
=20
it?

Regards,
&rzej

--=20




------=_Part_346_19835069.1356185406401
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

<br><br>W dniu =B6roda, 19 grudnia 2012 12:58:41 UTC+1 u=BFytkownik Olaf va=
n der Spek napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Wed, D=
ec 19, 2012 at 12:50 PM, Andrzej Krzemie=F1ski
<br>&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
zMnn5Gv4xSIJ">akrz...@gmail.com</a>&gt; wrote:
<br>&gt;&gt;&gt; What if the arguments can't (or shouldn't) be copied?
<br>&gt;&gt;&gt;
<br>&gt;&gt;&gt; class C : noncopyable;
<br>&gt;&gt;&gt;
<br>&gt;&gt;&gt; C default;
<br>&gt;&gt;&gt; C* a =3D ...;
<br>&gt;&gt;&gt; C&amp; b =3D get_value_or(a, default);
<br>&gt;&gt;&gt; b.do_something();
<br>&gt;&gt;
<br>&gt;&gt;
<br>&gt;&gt; Bad example, a isn't a temporary.
<br>&gt;&gt;
<br>&gt;&gt; C* a();
<br>&gt;&gt;
<br>&gt;&gt; C&amp; b =3D get_value_or(a(), default);
<br>&gt;
<br>&gt;
<br>&gt; I think something is wrong with this example: a() does not return =
an
<br>&gt; optional. But to answer your initial question "What if the argumen=
ts can't
<br>&gt; (or shouldn't) be copied?" -- if the semantics of get_value_or do =
not suit
<br>&gt; your needs you should resort to other tools: ternary operator or s=
ome such.
<br>
<br>I assumed get_value_or would support pointers too ("This function
<br>template could be equally well be applied to any type satysfying the
<br>requirements of NullableProxy."), but I guess it doesn't. So it's not
<br>as generic as it could be.
<br>A ternary operator isn't suitable if one or both of the arguments are u=
nnamed.
<br></blockquote><div><br>OK, my reply was too scarce. The goal of this fun=
ction was to assist with the most common use case, where the T in optional =
is int or std::string.<br><br><div class=3D"prettyprint" style=3D"backgroun=
d-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style=
: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettypr=
int"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">optional</span><span style=3D"color: #080;" class=3D"styl=
ed-by-prettify">&lt;int&gt;</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> getCount</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">int</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> ans=
 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> get_value_or</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">getCount</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(),</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
066;" class=3D"styled-by-prettify">0</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span></div></code></div><br>In these cases the func=
tion works fine, although the notation would be cleaner if it was a member =
function. <br><br><code class=3D"prettyprint"><div class=3D"prettyprint" st=
yle=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 18=
7); border-style: solid; border-width: 1px; word-wrap: break-word;"><code c=
lass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> ans </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> getCount</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">().</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">get_value_or</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">(</span><span style=3D"color: #066;" class=3D"styled-by-prettify=
">0</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></di=
v></code></div><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r><span style=3D"font-family: arial,sans-serif;">We do not expect of it to =
be a general purpose tool for every possible usage. For some usages you wil=
l have to resort to other means.<br><br>We also considered generalizing it =
to any NullableProxy, but it comes with certain difficulties. Because optio=
nal&lt;T&gt; owns the T we can optimize our function for rvalue references:=
 we can move the T. This would be disastrous for rvalues of pointer type.<b=
r><br>Also, you mentioned earlier that <span style=3D"font-family: courier =
new,monospace;">get_value_or</span> doesn't work for non-Novable types. One=
 of the reasons for that is that is that we wanted to prevent dangling refe=
rences. The other reason is that it is difficult to imagine how you would l=
ike to use </span></span></code><code class=3D"prettyprint"><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><span style=3D"font-family: aria=
l,sans-serif;"><code class=3D"prettyprint"><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><span style=3D"font-family: arial,sans-serif;"><s=
pan style=3D"font-family: courier new,monospace;">get_value_or</span></span=
></span></code></span> <span style=3D"font-family: arial,sans-serif;">with<=
/span> T</span></code><code class=3D"prettyprint"><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><span style=3D"font-family: arial,sans-ser=
if;">'s that are not movable. Hence the part "value" in function name. Do y=
ou know of a real-life use case for it?</span></span></code><br><br>Regards=
,<br>&amp;rzej<br><br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_346_19835069.1356185406401--

.


Author: Vladimir Batov <vb.mail.247@gmail.com>
Date: Sat, 22 Dec 2012 14:07:31 -0800 (PST)
Raw View
------=_Part_479_3986822.1356214051045
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

Andrzej,

On Friday, September 7, 2012 6:35:30 AM UTC+10, Andrzej Krzemie=F1ski wrote=
:
>
> Hi Everybody,
> In a couple of days we will be submitting the proposal for std::optional.=
=20
> The proposal revised based on the input from people in this list is=20
> available under the same link:=20
> http://kojot.sggw.waw.pl/~akrzemi1/optional/tr2.optional.proposal.html.
> If you would still like to review or discuss it or propose any=20
> improvements, here is your chance.
> ...


1. I wish I had your stamina and perseverance to see a job through. Quite=
=20
impressive. While reading I had a few how-about-that moments just to see=20
them addressed/explained/mentioned later. :-)
2. Well, you do not probably want to re-open the discussion/debate again=20
given the timeframe -- "In a couple of days we will be submitting the=20
proposal", right?
3. Please do not drop the in-place constructor. :-) IMO it's very much=20
idiomatic in C++ -- declaration is initialization. The two-liner does the=
=20
same but in the C style, i.e. open for mis-use, harder to trace/debug.
4. Why not a tag dependent on T? I am really not that convinced that cases=
=20
like

void fun(optional<string>);
void fun(optional<int>);
fun(nullopt); *// ambiguous*


are really that rare. Surely, the standard function overloading like=20
fun(string) and fun(int) is far from rare. Throwing 'optional' into the mix=
=20
is only natural IMO.=20

3. Did not see the optional references discussion even though Fernando=20
Cacciola mentioned it's been going on for years. :-) Sounds quite=20
interesting and useful... and I suspect a source for much debate.=20

4. Good luck with the proposal and all the very best.=20

V.


--=20




------=_Part_479_3986822.1356214051045
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

Andrzej,<br><br>On Friday, September 7, 2012 6:35:30 AM UTC+10, Andrzej Krz=
emie=F1ski wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Hi Everybody,=
<br>In a couple of days we will be submitting the proposal for std::optiona=
l. The proposal revised based on the input from people in this list is avai=
lable under the same link: <a href=3D"http://kojot.sggw.waw.pl/%7Eakrzemi1/=
optional/tr2.optional.proposal.html" target=3D"_blank">http://kojot.sggw.wa=
w.pl/~<wbr>akrzemi1/optional/tr2.<wbr>optional.proposal.html</a>.<br>If you=
 would still like to review or discuss it or propose any improvements, here=
 is your chance.<br>...</blockquote><div><br></div><div>1. I wish I had you=
r stamina and&nbsp;perseverance to see a job through. Quite impressive.&nbs=
p;While reading I had a few how-about-that&nbsp;moments just to see them ad=
dressed/explained/mentioned later. :-)</div><div>2. Well, you do not probab=
ly want to re-open the discussion/debate again given the timeframe -- "In a=
 couple of days we will be submitting the proposal", right?</div><div>3. Pl=
ease do not drop the in-place constructor. :-) IMO it's very much idiomatic=
 in C++ -- declaration is initialization. The two-liner does the same but i=
n the C style, i.e. open for mis-use, harder to trace/debug.</div><div><spa=
n style=3D"color: rgb(0, 0, 0); font-family: Arial;">4.&nbsp;</span><a name=
=3D"rationale.t_based_none" style=3D"font-family: Arial;">Why not a tag dep=
endent on&nbsp;<code>T</code>?&nbsp;</a><a name=3D"rationale.t_based_none" =
style=3D"font-family: Arial;"><span style=3D"color: rgb(0, 0, 0); font-size=
: medium;">I am really not that convinced that cases like</span></a><br></d=
iv><div><a name=3D"rationale.t_based_none"><span style=3D"color: rgb(0, 0, =
0); font-family: Arial; font-size: medium;"><br></span></a></div><div><a na=
me=3D"rationale.t_based_none"><pre style=3D"margin-left: 20pt; color: rgb(0=
, 0, 0); font-size: medium;">void fun(optional&lt;string&gt;);
void fun(optional&lt;int&gt;);
fun(nullopt); <em style=3D"font-family: 'OCR A Extended', Consolas, 'Lucida=
 Console', monospace;">// ambiguous</em>
</pre></a><p style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: m=
edium; line-height: normal;"><a name=3D"rationale.t_based_none"></a><a name=
=3D"rationale.t_based_none"></a></p><p style=3D"color: rgb(0, 0, 0); font-s=
ize: medium; line-height: normal; display: inline !important;"><a name=3D"r=
ationale.t_based_none"><br></a></p><p></p><p style=3D"color: rgb(0, 0, 0); =
font-family: Arial; font-size: medium; line-height: normal;"><a name=3D"rat=
ionale.t_based_none"></a></p><p style=3D"color: rgb(0, 0, 0); font-size: me=
dium; line-height: normal; display: inline !important;"><a name=3D"rational=
e.t_based_none">are really that rare. Surely, the standard function overloa=
ding like fun(string) and fun(int) is far from rare. Throwing 'optional' in=
to the mix is only natural IMO.&nbsp;</a></p><br><p></p><p style=3D"color: =
rgb(0, 0, 0); font-family: Arial; font-size: medium; line-height: normal;">=
<a name=3D"rationale.t_based_none"></a></p><p style=3D"color: rgb(0, 0, 0);=
 font-size: medium; line-height: normal; display: inline !important;"><a na=
me=3D"rationale.t_based_none">3. Did not see the optional references discus=
sion even though Fernando Cacciola mentioned it's been going on for years. =
:-) Sounds quite interesting and useful... and I suspect a source for much =
debate.&nbsp;</a></p><p></p><p style=3D"color: rgb(0, 0, 0); font-family: A=
rial; font-size: medium; line-height: normal;"><a name=3D"rationale.t_based=
_none"></a></p><p style=3D"color: rgb(0, 0, 0); font-size: medium; line-hei=
ght: normal; display: inline !important;"><a name=3D"rationale.t_based_none=
">4. Good luck with the proposal and all the very best.&nbsp;</a></p><p></p=
><p style=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: medium; li=
ne-height: normal;"><a name=3D"rationale.t_based_none"></a></p><p style=3D"=
color: rgb(0, 0, 0); font-size: medium; line-height: normal; display: inlin=
e !important;"><a name=3D"rationale.t_based_none">V.</a></p><p></p><p style=
=3D"color: rgb(0, 0, 0); font-family: Arial; font-size: medium; line-height=
: normal;"><span style=3D"color: rgb(0, 0, 0); font-family: Arial; font-siz=
e: medium;"><br></span></p></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_479_3986822.1356214051045--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Sun, 23 Dec 2012 00:23:46 +0200
Raw View
On 23 December 2012 00:07, Vladimir Batov <vb.mail.247@gmail.com> wrote:
> 3. Please do not drop the in-place constructor. :-) IMO it's very much
> idiomatic in C++ -- declaration is initialization. The two-liner does the
> same but in the C style, i.e. open for mis-use, harder to trace/debug.

I haven't heard any mention about dropping the emplace_t constructor.

> 4. Why not a tag dependent on T? I am really not that convinced that cases

Because it's harder to read and write.

> void fun(optional<string>);
> void fun(optional<int>);
> fun(nullopt); // ambiguous
> are really that rare. Surely, the standard function overloading like

Those cases are extremely rare, they are ill-formed due to the ambiguity. :)
The work-around is
fun(optional<string>{});

and it's working around a

fun(optional<string>::nullopt);

so I think it's better to have a global nullopt and have the
work-around for those who
need it.
> fun(string) and fun(int) is far from rare. Throwing 'optional' into the mix

--




.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Sat, 22 Dec 2012 17:05:32 -0600
Raw View
--000e0cd3b600c0677104d1790257
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On 22 December 2012 16:07, Vladimir Batov <vb.mail.247@gmail.com> wrote:

> On Friday, September 7, 2012 6:35:30 AM UTC+10, Andrzej Krzemie=C5=84ski =
wrote:
>
>> 2. Well, you do not probably want to re-open the discussion/debate again
>> given the timeframe
>>
>
You do realize you are replying to a 3 and a half month old message, right?
--=20
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--=20




--000e0cd3b600c0677104d1790257
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On 22 December 2012 16:07, Vladimir Batov <span dir=3D"ltr">&lt;<a href=3D"=
mailto:vb.mail.247@gmail.com" target=3D"_blank">vb.mail.247@gmail.com</a>&g=
t;</span> wrote:<br><div class=3D"gmail_quote"><blockquote class=3D"gmail_q=
uote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1e=
x">

<div class=3D"im">On Friday, September 7, 2012 6:35:30 AM UTC+10, Andrzej K=
rzemie=C5=84ski wrote:</div><blockquote class=3D"gmail_quote" style=3D"marg=
in:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div cl=
ass=3D"im">

2. Well, you do not probably want to re-open the discussion/debate again gi=
ven the timeframe</div></blockquote></blockquote><div><br></div><div>You do=
 realize you are replying to a 3 and a half month old message, right?</div>

</div>-- <br>=C2=A0Nevin &quot;:-)&quot; Liber=C2=A0 &lt;mailto:<a href=3D"=
mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a>=
&gt;=C2=A0 (847) 691-1404

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--000e0cd3b600c0677104d1790257--

.


Author: Vladimir Batov <vb.mail.247@gmail.com>
Date: Sun, 23 Dec 2012 10:15:22 +1100
Raw View
On Sun, Dec 23, 2012 at 9:23 AM, Ville Voutilainen
<ville.voutilainen@gmail.com> wrote:
> On 23 December 2012 00:07, Vladimir Batov <vb.mail.247@gmail.com> wrote:
>> 3. Please do not drop the in-place constructor. :-) IMO it's very much
>> idiomatic in C++ -- declaration is initialization. The two-liner does the
>> same but in the C style, i.e. open for mis-use, harder to trace/debug.
>
> I haven't heard any mention about dropping the emplace_t constructor.

From Andrzej's original post:

The in-place constructor is not strictly necessary. It could be
dropped because one can always achieve the same effect with a
two-liner:

optional<Guard> oj;                        // start disengaged
oj.emplace("arg");                         // now engage

>> 4. Why not a tag dependent on T? I am really not that convinced that cases
>
> Because it's harder to read and write.

Oh, c'mon... :-) after years of reading C++, is optional<T>::nullopt
really that hard to read and write? Typedefs anyone?

>> void fun(optional<string>);
>> void fun(optional<int>);
>> fun(nullopt); // ambiguous
>> are really that rare. Surely, the standard function overloading like
>
> Those cases are extremely rare, they are ill-formed due to the ambiguity. :)

Well, again, I guess we have to agree to disagree. You say, (if I
understand) overloading is "extremely rare" and I say it's a
commonplace. I have foo(int) and foo(string) everywhere and adding
optional to it seems like a natural step forward to me.

> The work-around is
> fun(optional<string>{});
>
> and it's working around a
>
> fun(optional<string>::nullopt);

Understood. Just does not feel exactly fair given that nullopt is not
for everyone and I can't agree with your "rare" argument. No drama
though.

--




.


Author: Vladimir Batov <vb.mail.247@gmail.com>
Date: Sun, 23 Dec 2012 10:22:14 +1100
Raw View
Jeez, indeed! I am sure I saw 21st Dec time stamp. Gosh, that's
embarrassing! Thank you for pointing it out. Sorry for the noise.

On Sun, Dec 23, 2012 at 10:05 AM, Nevin Liber <nevin@eviloverlord.com> wrot=
e:
> On 22 December 2012 16:07, Vladimir Batov <vb.mail.247@gmail.com> wrote:
>>
>> On Friday, September 7, 2012 6:35:30 AM UTC+10, Andrzej Krzemie=F1ski wr=
ote:
>>>
>>> 2. Well, you do not probably want to re-open the discussion/debate agai=
n
>>> given the timeframe
>
>
> You do realize you are replying to a 3 and a half month old message, righ=
t?
> --
>  Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404
>
> --
>
>
>

--=20




.


Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Sun, 23 Dec 2012 00:42:42 -0800 (PST)
Raw View
------=_Part_608_16120209.1356252162411
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable



W dniu niedziela, 23 grudnia 2012 00:22:14 UTC+1 u=BFytkownik Vladimir Bato=
v=20
napisa=B3:
>
> Jeez, indeed! I am sure I saw 21st Dec time stamp. Gosh, that's=20
> embarrassing! Thank you for pointing it out. Sorry for the noise.=20
>

Indeed, the second revision of the optional has been already submitted to=
=20
the committee. See here:=20
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3406.html
We plan the next revision to include the following changes:

   - Add hash support (whenever T is hashable)
   - Split the proposal: one for optional values, the other(s) for optional=
=20
   references
   - Make optional a literal type (usable in compile-time computations)=20
   (this is possible, see the following for the proof of concept:=20
   https://github.com/akrzemi1/Optional)=20

The in-place (explicit) constructor is still there. Regarding the=20
typed-vs-non-typed nullopt tag, while I can understand (I think) your point=
=20
of view, the situation here looks to me like a controversial issue that=20
simply needs to be resolved by an arbitrary call. The reason I pick the=20
non-typed one is because (1) I like them, (2) they are the current practice=
=20
in Boost, (3) You can still emulate the typed-tag as others indicated, but=
=20
you couldn't emulate the non-typed tag if null-opt were typed.

Regards,
&rzej

--=20




------=_Part_608_16120209.1356252162411
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

<br><br>W dniu niedziela, 23 grudnia 2012 00:22:14 UTC+1 u=BFytkownik Vladi=
mir Batov napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Jeez, inde=
ed! I am sure I saw 21st Dec time stamp. Gosh, that's
<br>embarrassing! Thank you for pointing it out. Sorry for the noise.
<br></blockquote><div><br>Indeed, the second revision of the optional has b=
een already submitted to the committee. See here: <a href=3D"http://www.ope=
n-std.org/jtc1/sc22/wg21/docs/papers/2012/n3406.html">http://www.open-std.o=
rg/jtc1/sc22/wg21/docs/papers/2012/n3406.html</a><br>We plan the next revis=
ion to include the following changes:<br><ul><li>Add hash support (whenever=
 T is hashable)</li><li>Split the proposal: one for optional values, the ot=
her(s) for optional references</li><li>Make optional a literal type (usable=
 in compile-time computations) (this is possible, see the following for the=
 proof of concept: <a href=3D"https://github.com/akrzemi1/Optional">https:/=
/github.com/akrzemi1/Optional</a>)&nbsp;</li></ul><p>The in-place (explicit=
) constructor is still there. Regarding the typed-vs-non-typed nullopt tag,=
 while I can understand (I think) your point of view, the situation here lo=
oks to me like a controversial issue that simply needs to be resolved by an=
 arbitrary call. The reason I pick the non-typed one is because (1) I like =
them, (2) they are the current practice in Boost, (3) You can still emulate=
 the typed-tag as others indicated, but you couldn't emulate the non-typed =
tag if null-opt were typed.</p><p>Regards,<br>&amp;rzej<br></p></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_608_16120209.1356252162411--

.


Author: Vladimir Batov <vb.mail.247@gmail.com>
Date: Sun, 23 Dec 2012 21:27:42 +1100
Raw View
Thanks, Andrzej, for the update. It's much appreciated. Sorry, for my
limping so late to the party and pretending I was on time. :-) As for
future plans, they sound really good... and dear-to-my-heart in-place
constructor is still there... as for nullopt, well, one can't have it
all. No drama. :-)

Thanks again,
V.

On Sun, Dec 23, 2012 at 7:42 PM, Andrzej Krzemie=F1ski <akrzemi1@gmail.com>=
 wrote:
>
>
> W dniu niedziela, 23 grudnia 2012 00:22:14 UTC+1 u=BFytkownik Vladimir Ba=
tov
> napisa=B3:
>>
>> Jeez, indeed! I am sure I saw 21st Dec time stamp. Gosh, that's
>> embarrassing! Thank you for pointing it out. Sorry for the noise.
>
>
> Indeed, the second revision of the optional has been already submitted to
> the committee. See here:
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3406.html
> We plan the next revision to include the following changes:
>
> Add hash support (whenever T is hashable)
> Split the proposal: one for optional values, the other(s) for optional
> references
> Make optional a literal type (usable in compile-time computations) (this =
is
> possible, see the following for the proof of concept:
> https://github.com/akrzemi1/Optional)
>
> The in-place (explicit) constructor is still there. Regarding the
> typed-vs-non-typed nullopt tag, while I can understand (I think) your poi=
nt
> of view, the situation here looks to me like a controversial issue that
> simply needs to be resolved by an arbitrary call. The reason I pick the
> non-typed one is because (1) I like them, (2) they are the current practi=
ce
> in Boost, (3) You can still emulate the typed-tag as others indicated, bu=
t
> you couldn't emulate the non-typed tag if null-opt were typed.
>
> Regards,
> &rzej
>
> --
>
>
>

--=20




.


Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Sun, 23 Dec 2012 16:05:06 +0100
Raw View
On Sat, Dec 22, 2012 at 3:10 PM, Andrzej Krzemie=F1ski <akrzemi1@gmail.com>=
 wrote:
> We do not expect of it to be a general purpose tool for every possible
> usage. For some usages you will have to resort to other means.

Sure, but having a less generic than necessary/possible function seems
like a missed opportunity.

> We also considered generalizing it to any NullableProxy, but it comes wit=
h
> certain difficulties. Because optional<T> owns the T we can optimize our
> function for rvalue references: we can move the T. This would be disastro=
us
> for rvalues of pointer type.

Wouldn't that still be possible by specializing the more generic variant?

> Also, you mentioned earlier that get_value_or doesn't work for non-Novabl=
e
> types. One of the reasons for that is that is that we wanted to prevent
> dangling references.

> The other reason is that it is difficult to imagine how
> you would like to use get_value_or with T's that are not movable. Hence t=
he
> part "value" in function name. Do you know of a real-life use case for it=
?

For a generic function returning "a ? *a : b" ? Yes
I've got a find function returning string*. If it returns 0, I want to
use a default string (static const). I don't want the strings to be
copied.

For boost::optional? If get_value_or is used with named parameters.
You already said in that case ? : is better, but it seems kinda weird
having to use another function/operator just depending on whether the
parameter is named.


--=20
Olaf

--=20




.


Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Sun, 23 Dec 2012 08:41:04 -0800 (PST)
Raw View
------=_Part_95_30122462.1356280865041
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable



W dniu niedziela, 23 grudnia 2012 16:05:06 UTC+1 u=BFytkownik Olaf van der=
=20
Spek napisa=B3:
>
> On Sat, Dec 22, 2012 at 3:10 PM, Andrzej Krzemie=F1ski <akrz...@gmail.com=
<javascript:>>=20
> wrote:=20
> > We do not expect of it to be a general purpose tool for every possible=
=20
> > usage. For some usages you will have to resort to other means.=20
>
> Sure, but having a less generic than necessary/possible function seems=20
> like a missed opportunity.=20
>

Personally, I do not find "missed opportunity" alone a strong enough=20
argument. The feedback we got at some point that it may be better to start=
=20
with something more concrete and generalize later, when we gain experience,=
=20
rather than overgeneralize too quickly. I never thought anyone would want=
=20
to use get_value_or could be used with pointers.
=20

>
> > We also considered generalizing it to any NullableProxy, but it comes=
=20
> with=20
> > certain difficulties. Because optional<T> owns the T we can optimize ou=
r=20
> > function for rvalue references: we can move the T. This would be=20
> disastrous=20
> > for rvalues of pointer type.=20
>
> Wouldn't that still be possible by specializing the more generic variant?=
=20
>

This would work if we only consider pointers and optionals. In the very=20
generic case of NullableProxy, it is not clear what we should assume: does=
=20
it own the referred-to object or not?
=20

>
> > Also, you mentioned earlier that get_value_or doesn't work for=20
> non-Novable=20
> > types. One of the reasons for that is that is that we wanted to prevent=
=20
> > dangling references.=20
>
> > The other reason is that it is difficult to imagine how=20
> > you would like to use get_value_or with T's that are not movable. Hence=
=20
> the=20
> > part "value" in function name. Do you know of a real-life use case for=
=20
> it?=20
>
> For a generic function returning "a ? *a : b" ? Yes=20
> I've got a find function returning string*. If it returns 0, I want to=20
> use a default string (static const). I don't want the strings to be=20
> copied.


Have you ever used such design in practise?=20

>
>
> For boost::optional? If get_value_or is used with named parameters.=20
> You already said in that case ? : is better, but it seems kinda weird=20
> having to use another function/operator just depending on whether the=20
> parameter is named.=20
>

Ok, I buy this argument. On the other hand, the advantage of get_value_or=
=20
compared to operator?: i only essential for unnamed (i.e., temporary)=20
objects. In that case we never copy, but move.

Regards,
&rzej=20

--=20




------=_Part_95_30122462.1356280865041
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

<br><br>W dniu niedziela, 23 grudnia 2012 16:05:06 UTC+1 u=BFytkownik Olaf =
van der Spek napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Sat,=
 Dec 22, 2012 at 3:10 PM, Andrzej Krzemie=F1ski &lt;<a href=3D"javascript:"=
 target=3D"_blank" gdf-obfuscated-mailto=3D"rIE85qm7dtkJ">akrz...@gmail.com=
</a>&gt; wrote:
<br>&gt; We do not expect of it to be a general purpose tool for every poss=
ible
<br>&gt; usage. For some usages you will have to resort to other means.
<br>
<br>Sure, but having a less generic than necessary/possible function seems
<br>like a missed opportunity.
<br></blockquote><div><br>Personally, I do not find "missed opportunity" al=
one a strong enough argument. The feedback we got at some point that it may=
 be better to start with something more concrete and generalize later, when=
 we gain experience, rather than overgeneralize too quickly. I never though=
t anyone would want to use get_value_or could be used with pointers.<br>&nb=
sp;<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>&gt; We also considered generalizing it to any NullableProxy, but it co=
mes with
<br>&gt; certain difficulties. Because optional&lt;T&gt; owns the T we can =
optimize our
<br>&gt; function for rvalue references: we can move the T. This would be d=
isastrous
<br>&gt; for rvalues of pointer type.
<br>
<br>Wouldn't that still be possible by specializing the more generic varian=
t?
<br></blockquote><div><br>This would work if we only consider pointers and =
optionals. In the very generic case of NullableProxy, it is not clear what =
we should assume: does it own the referred-to object or not?<br>&nbsp;<br><=
/div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>&gt; Also, you mentioned earlier that get_value_or doesn't work for non=
-Novable
<br>&gt; types. One of the reasons for that is that is that we wanted to pr=
event
<br>&gt; dangling references.
<br>
<br>&gt; The other reason is that it is difficult to imagine how
<br>&gt; you would like to use get_value_or with T's that are not movable. =
Hence the
<br>&gt; part "value" in function name. Do you know of a real-life use case=
 for it?
<br>
<br>For a generic function returning "a ? *a : b" ? Yes
<br>I've got a find function returning string*. If it returns 0, I want to
<br>use a default string (static const). I don't want the strings to be
<br>copied.</blockquote><div><br>Have you ever used such design in practise=
? <br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>
<br>For boost::optional? If get_value_or is used with named parameters.
<br>You already said in that case ? : is better, but it seems kinda weird
<br>having to use another function/operator just depending on whether the
<br>parameter is named.
<br></blockquote><div><br>Ok, I buy this argument. On the other hand, the a=
dvantage of get_value_or compared to operator?: i only essential for unname=
d (i.e., temporary) objects. In that case we never copy, but move.<br><br>R=
egards,<br>&amp;rzej <br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_95_30122462.1356280865041--

.


Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Sun, 23 Dec 2012 18:25:40 +0100
Raw View
On Sun, Dec 23, 2012 at 5:41 PM, Andrzej Krzemie=C5=84ski <akrzemi1@gmail.c=
om> wrote:
>> > We also considered generalizing it to any NullableProxy, but it comes
>> > with
>> > certain difficulties. Because optional<T> owns the T we can optimize o=
ur
>> > function for rvalue references: we can move the T. This would be
>> > disastrous
>> > for rvalues of pointer type.
>>
>> Wouldn't that still be possible by specializing the more generic variant=
?
>
>
> This would work if we only consider pointers and optionals. In the very
> generic case of NullableProxy, it is not clear what we should assume: doe=
s
> it own the referred-to object or not?

Assuming that doesn't seem safe, so I'd go for no.

>> For a generic function returning "a ? *a : b" ? Yes
>> I've got a find function returning string*. If it returns 0, I want to
>> use a default string (static const). I don't want the strings to be
>> copied.
>
>
> Have you ever used such design in practise?

Yes, see http://code.google.com/p/xbt/source/browse/trunk/xbt/misc/xbt/find=
_ptr.h

find_ptr is a wrapper around (unordered) map::find that returns a
pointer to second or NULL.
With map<int, string>, it'd return string*.

find_ref is a wrapper that returns a reference to second or to the
third argument.
find_ref(map, key, default)) is basically get_value_or(find_ptr(map,
key), value);

I did consider writing my own get_value_or (or if_null, like the MySQL
function), but decided to combine that and find_ptr.

Those functions are specific to maps, but I can imagine get_value_or
being or something like it to be useful for other cases too.

>> For boost::optional? If get_value_or is used with named parameters.
>> You already said in that case ? : is better, but it seems kinda weird
>> having to use another function/operator just depending on whether the
>> parameter is named.
>
>
> Ok, I buy this argument. On the other hand, the advantage of get_value_or
> compared to operator?: i only essential for unnamed (i.e., temporary)
> objects. In that case we never copy, but move.

Isn't that still less efficient than returning a reference in certain cases=
?
What if you can't move from the default value, would you copy it each time?

static const string d =3D "Olaf";
void f(const boost::optional<string>&);

f(get_value_or(..., d));

BTW, I'm not trying to cause any trouble, just trying to get things as
good as possible.

The dangling reference problem is a problem in other cases too, IIRC
it came up with a minmax problem too.
--=20
Olaf

--=20




.


Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Sun, 23 Dec 2012 16:57:22 -0300
Raw View
Hi Olaf,

On Sun, Dec 23, 2012 at 2:25 PM, Olaf van der Spek <olafvdspek@gmail.com> w=
rote:
> On Sun, Dec 23, 2012 at 5:41 PM, Andrzej Krzemie=C5=84ski <akrzemi1@gmail=
..com> wrote:
>>> > We also considered generalizing it to any NullableProxy, but it comes
>>> > with
>>> > certain difficulties. Because optional<T> owns the T we can optimize =
our
>>> > function for rvalue references: we can move the T. This would be
>>> > disastrous
>>> > for rvalues of pointer type.
>>>
>>> Wouldn't that still be possible by specializing the more generic varian=
t?
>>

I, and I guess most people, would most definitely like to have a
general purpose get_value_or() utility that works on all NullableProxy
models.
OTOH, specifying that is not as trivial as it seems. Or that least we
haven't been able to do so. Thus, we decided to keep it focused on
optional<>, to avoid making it a cause of controversy.

However, your suggestion seems to be based on the assumption, or
knowledge, that it is in fact possible to specify a general version
that is beyond any potential controversy, or at least any significant
one.

So, what is it? How would you specify that? If it works we'll be happy
to put it in the proposal.

Best

--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com

--=20




.


Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Wed, 26 Dec 2012 01:18:19 +0100
Raw View
On Sun, Dec 23, 2012 at 8:57 PM, Fernando Cacciola
<fernando.cacciola@gmail.com> wrote:
>>>> Wouldn't that still be possible by specializing the more generic variant?
>>>
>
> I, and I guess most people, would most definitely like to have a
> general purpose get_value_or() utility that works on all NullableProxy
> models.
> OTOH, specifying that is not as trivial as it seems. Or that least we
> haven't been able to do so. Thus, we decided to keep it focused on
> optional<>, to avoid making it a cause of controversy.
>
> However, your suggestion seems to be based on the assumption, or
> knowledge, that it is in fact possible to specify a general version
> that is beyond any potential controversy, or at least any significant
> one.

Hi Fernando,

I'm hoping it's possible and was assuming it wouldn't be too hard.
But it seems even get_value_or for optional isn't trivial.
--
Olaf

--




.


Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Thu, 27 Dec 2012 05:12:30 -0800 (PST)
Raw View
------=_Part_1776_14126822.1356613950909
Content-Type: text/plain; charset=ISO-8859-1



> >>> Wouldn't that still be possible by specializing the more generic
> variant?
> >>
>
> I, and I guess most people, would most definitely like to have a
> general purpose get_value_or() utility that works on all NullableProxy
> models.
> OTOH, specifying that is not as trivial as it seems. Or that least we
> haven't been able to do so. Thus, we decided to keep it focused on
> optional<>, to avoid making it a cause of controversy.
>

Perhaps for the time being (i.e. for the scope of Revision 3) we should
change get_value_or to be only optional's member function. This way we do
not rise false expectations, and do not commit to the function's
signature/semantics that we later may not be able to properly generalize. A
member function has one additional advantage: it is (at least IMO) easier
to read. Compare:

int ans = get_value_or( findCount("male", 1, 9), -1 );

and

int ans =  findCount("male", 1, 9).get_value_or(-1);

Regards,
&rzej

--




------=_Part_1776_14126822.1356613950909
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;">&gt;&gt;&gt; Wouldn't that=
 still be possible by specializing the more generic variant?
<br>&gt;&gt;
<br>
<br>I, and I guess most people, would most definitely like to have a
<br>general purpose get_value_or() utility that works on all NullableProxy
<br>models.
<br>OTOH, specifying that is not as trivial as it seems. Or that least we
<br>haven't been able to do so. Thus, we decided to keep it focused on
<br>optional&lt;&gt;, to avoid making it a cause of controversy.
<br></blockquote><div><br>Perhaps for the time being (i.e. for the scope of=
 Revision 3) we should change get_value_or to be only optional's member fun=
ction. This way we do not rise false expectations, and do not commit to the=
 function's signature/semantics that we later may not be able to properly g=
eneralize. A member function has one additional advantage: it is (at least =
IMO) easier to read. Compare:<br><br><div class=3D"prettyprint" style=3D"ba=
ckground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); borde=
r-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"p=
rettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> ans </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> get_value_or</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 findCount</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><span style=3D"color: #080;" class=3D"styled-by-prettify">"male"</s=
pan><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: #066;" class=3D"styled-by-prettify">1</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"sty=
led-by-prettify">9</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">),</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: #066;" class=3D"styled-by-prettify">1</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br></span></div></code></div><br>and<br><br=
><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); =
border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; w=
ord-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyp=
rint"><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> ans </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> &nbsp;findCount</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D=
"color: #080;" class=3D"styled-by-prettify">"male"</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=
=3D"styled-by-prettify">1</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">9</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">).</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">get_value_or</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(-</span><span sty=
le=3D"color: #066;" class=3D"styled-by-prettify">1</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br></span></div></code></div><br>Regards,<=
br>&amp;rzej<br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_1776_14126822.1356613950909--

.


Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Thu, 27 Dec 2012 10:24:28 -0300
Raw View
On Thu, Dec 27, 2012 at 10:12 AM, Andrzej Krzemie=C5=84ski
<akrzemi1@gmail.com> wrote:
>
>> >>> Wouldn't that still be possible by specializing the more generic
>> >>> variant?
>> >>
>>
>> I, and I guess most people, would most definitely like to have a
>> general purpose get_value_or() utility that works on all NullableProxy
>> models.
>> OTOH, specifying that is not as trivial as it seems. Or that least we
>> haven't been able to do so. Thus, we decided to keep it focused on
>> optional<>, to avoid making it a cause of controversy.
>
>
> Perhaps for the time being (i.e. for the scope of Revision 3) we should
> change get_value_or to be only optional's member function. This way we do
> not rise false expectations, and do not commit to the function's
> signature/semantics that we later may not be able to properly generalize.=
 A
> member function has one additional advantage: it is (at least IMO) easier=
 to
> read. Compare:
>
> int ans =3D get_value_or( findCount("male", 1, 9), -1 );
>
> and
>
> int ans =3D  findCount("male", 1, 9).get_value_or(-1);
>

Actually, I prefer to keep the free function.

The reason is that, while we would only specify an overload for
optional values, being a free function nothing prevents it from being
further extended to other types.
This is the nice thing about free functions, they provide a scalable
interface that can be non-intrusively extended. That is the reason why
I didn't make it a member function to begin with.

It is true that this decision makes a certain commitment to a
signature and expected semantics on the std namespace, but for this
particular case I don't see that as a problem.

Also, I don't find the member easier to read at all. In generic C++,
free functions are very common (for the reasons I've exposed above).
Boost is full of that, and as a close match, consider get_pointer().

Best

--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com

--=20




.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Thu, 27 Dec 2012 15:52:42 -0600
Raw View
--0015174c12ce7031f404d1dc9303
Content-Type: text/plain; charset=ISO-8859-1

On 27 December 2012 07:24, Fernando Cacciola <fernando.cacciola@gmail.com>wrote:

>
> Actually, I prefer to keep the free function.
>
> The reason is that, while we would only specify an overload for
> optional values, being a free function nothing prevents it from being
> further extended to other types.
>

Unlike begin(), end() and swap(), I'm having a hard time imagining
extending get_value_or() in a generic way where I don't care what the
underlying type is.  It is one thing to, say change a vector<T> to a
list<T> and have iteration "just work", but I'm not seeing the equivalent
for get_value_or().  Do you have a use case?

While not a perfect replacement, I tend to use (foo ? *foo : make_value()),
as I usually don't want to pay the cost for make_value().  Plus, I don't
have to worry that other types might or (in all likelihood) might not
overload get_value_or().  This differs from begin(), end() and swap(),
because they already have definitions that take care of 90+% of the cases.


> It is true that this decision makes a certain commitment to a
> signature and expected semantics on the std namespace, but for this
>
particular case I don't see that as a problem.
>

Are you expecting people to overload this in namespace std?  Non-experts
are generally apprehensive about doing that.


To summarize:  I don't find this to be a useful customization point,
because I'm not seeing a use case for a context where someone is changing
an optional<T> to some other type (either explicitly or in generic code)
and expecting the rest of their code to "just work".
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--




--0015174c12ce7031f404d1dc9303
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On 27 December 2012 07:24, Fernando Cacciola <span dir=3D"ltr">&lt;<a href=
=3D"mailto:fernando.cacciola@gmail.com" target=3D"_blank">fernando.cacciola=
@gmail.com</a>&gt;</span> wrote:<br><div 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 class=3D"HOEnZb"><div class=3D"h5"><br>
</div></div>Actually, I prefer to keep the free function.<br>
<br>
The reason is that, while we would only specify an overload for<br>
optional values, being a free function nothing prevents it from being<br>
further extended to other types.<br></blockquote><div><br>Unlike begin(), e=
nd() and swap(), I&#39;m having a hard time imagining extending get_value_o=
r() in a generic way where I don&#39;t care what the underlying type is.=A0=
 It is one thing to, say change a vector&lt;T&gt; to a list&lt;T&gt; and ha=
ve iteration &quot;just work&quot;, but I&#39;m not seeing the equivalent f=
or get_value_or().=A0 Do you have a use case?<br>

<br>While not a perfect replacement, I tend to use (foo ? *foo : make_value=
()), as I usually don&#39;t want to pay the cost for make_value().=A0 Plus,=
 I don&#39;t have to worry that other types might or (in all likelihood) mi=
ght not overload get_value_or().=A0 This differs from begin(), end() and sw=
ap(), because they already have definitions that take care of 90+% of the c=
ases.<br>

=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde=
r-left:1px #ccc solid;padding-left:1ex">It is true that this decision makes=
 a certain commitment to a<br>
signature and expected semantics on the std namespace, but for this<br></bl=
ockquote><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde=
r-left:1px #ccc solid;padding-left:1ex">
particular case I don&#39;t see that as a problem.<br></blockquote><div><br=
>Are you expecting people to overload this in namespace std?=A0 Non-experts=
 are generally apprehensive about doing that.<br><br><br>To summarize:=A0 I=
 don&#39;t find this to be a useful customization point, because I&#39;m no=
t seeing a use case for a context where someone is changing an optional&lt;=
T&gt; to some other type (either explicitly or in generic code) and expecti=
ng the rest of their code to &quot;just work&quot;.<br clear=3D"all">

</div></div>-- <br>=A0Nevin &quot;:-)&quot; Liber=A0 &lt;mailto:<a href=3D"=
mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a>=
&gt;=A0 (847) 691-1404

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--0015174c12ce7031f404d1dc9303--

.


Author: Vladimir Batov <vb.mail.247@gmail.com>
Date: Thu, 27 Dec 2012 15:26:02 -0800 (PST)
Raw View
------=_Part_30_23684662.1356650762475
Content-Type: text/plain; charset=ISO-8859-1

On Friday, December 28, 2012 8:52:42 AM UTC+11, Nevin ":-)" Liber wrote:
>
> On 27 December 2012 07:24, Fernando Cacciola <fernando...@gmail.com<javascript:>
> > wrote:
>
>>
>> Actually, I prefer to keep the free function.
>>
>> The reason is that, while we would only specify an overload for
>> optional values, being a free function nothing prevents it from being
>> further extended to other types.
>>
>
> Unlike begin(), end() and swap(), I'm having a hard time imagining
> extending get_value_or() in a generic way where I don't care what the
> underlying type is.  It is one thing to, say change a vector<T> to a
> list<T> and have iteration "just work", but I'm not seeing the equivalent
> for get_value_or().  Do you have a use case?
>
> While not a perfect replacement, I tend to use (foo ? *foo :
> make_value()), as I usually don't want to pay the cost for make_value().
> Plus, I don't have to worry that other types might or (in all likelihood)
> might not overload get_value_or().  This differs from begin(), end() and
> swap(), because they already have definitions that take care of 90+% of the
> cases.
>
>
>> It is true that this decision makes a certain commitment to a
>> signature and expected semantics on the std namespace, but for this
>>
> particular case I don't see that as a problem.
>>
>
> Are you expecting people to overload this in namespace std?  Non-experts
> are generally apprehensive about doing that.
>
> To summarize:  I don't find this to be a useful customization point,
> because I'm not seeing a use case for a context where someone is changing
> an optional<T> to some other type (either explicitly or in generic code)
> and expecting the rest of their code to "just work".
>

I do understand the potential usefulness of the function. Still I can't
help thinking if trying so hard to find a place for it is really worth it.
I feel one way or the other (free or member function) it'll be hardly used
as I expect the ?: to be the preference by far. And if I remember correctly
quite a few optional-related APIs have been dismissed exactly for the
reason they were expected to be used very rarely. Well, at least it was the
official line. ;-) Neither adding to the std namespace for
potential/unproven extension nor adding to the optional api even though
optional itself does not need it seem like clear winners.

--




------=_Part_30_23684662.1356650762475
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On Friday, December 28, 2012 8:52:42 AM UTC+11, Nevin ":-)" Liber wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;">On 27 December 2012 07:24, Fernan=
do Cacciola <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank"=
 gdf-obfuscated-mailto=3D"bX20Zrj37xYJ">fernando...@gmail.com</a>&gt;</span=
> wrote:<br><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div><div><br>
</div></div>Actually, I prefer to keep the free function.<br>
<br>
The reason is that, while we would only specify an overload for<br>
optional values, being a free function nothing prevents it from being<br>
further extended to other types.<br></blockquote><div><br>Unlike begin(), e=
nd() and swap(), I'm having a hard time imagining extending get_value_or() =
in a generic way where I don't care what the underlying type is.&nbsp; It i=
s one thing to, say change a vector&lt;T&gt; to a list&lt;T&gt; and have it=
eration "just work", but I'm not seeing the equivalent for get_value_or().&=
nbsp; Do you have a use case?<br>

<br>While not a perfect replacement, I tend to use (foo ? *foo : make_value=
()), as I usually don't want to pay the cost for make_value().&nbsp; Plus, =
I don't have to worry that other types might or (in all likelihood) might n=
ot overload get_value_or().&nbsp; This differs from begin(), end() and swap=
(), because they already have definitions that take care of 90+% of the cas=
es.<br>

&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex">It is true that this decision ma=
kes a certain commitment to a<br>
signature and expected semantics on the std namespace, but for this<br></bl=
ockquote><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde=
r-left:1px #ccc solid;padding-left:1ex">
particular case I don't see that as a problem.<br></blockquote><div><br>Are=
 you expecting people to overload this in namespace std?&nbsp; Non-experts =
are generally apprehensive about doing that.<br><br>To summarize:&nbsp; I d=
on't find this to be a useful customization point, because I'm not seeing a=
 use case for a context where someone is changing an optional&lt;T&gt; to s=
ome other type (either explicitly or in generic code) and expecting the res=
t of their code to "just work".<br clear=3D"all">

</div></div></blockquote><div><br>I do understand the potential usefulness =
of the function. Still I can't help thinking if trying so hard to find a pl=
ace for it is really worth it. I feel one way or the other (free or member =
function) it'll be hardly used as I expect the ?: to be the preference by f=
ar. And if I remember correctly quite a few optional-related APIs have been=
 dismissed exactly for the reason they were expected to be used very rarely=
.. Well, at least it was the official line. ;-) Neither adding to the std na=
mespace for potential/unproven extension nor adding to the optional api eve=
n though optional itself does not need it seem like clear winners. <br></di=
v>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_30_23684662.1356650762475--

.


Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Fri, 28 Dec 2012 13:08:22 -0300
Raw View
On Thu, Dec 27, 2012 at 6:52 PM, Nevin Liber <nevin@eviloverlord.com> wrote:
> On 27 December 2012 07:24, Fernando Cacciola <fernando.cacciola@gmail.com>
> wrote:
>>
>>
>> Actually, I prefer to keep the free function.
>>
>> The reason is that, while we would only specify an overload for
>> optional values, being a free function nothing prevents it from being
>> further extended to other types.
>
>
> Unlike begin(), end() and swap(), I'm having a hard time imagining extending
> get_value_or() in a generic way where I don't care what the underlying type
> is.

Why?

Wouldn't you agree that the call:

get_value_or( something_that_might_have_a_value, default)

is very self explanatory and have quite clear semantics regardless of
the type of the parameters?

Maybe your point is the possibly disctintion between returning a
"copy" of the value vs a reference to it.
If that is the case, we already noticed for the case of
std::optional<> that it better be a copy of the value, and the reasons
why apply to just any type.

>  It is one thing to, say change a vector<T> to a list<T> and have
> iteration "just work", but I'm not seeing the equivalent for get_value_or().
> Do you have a use case?
>
I'm confused by your reference to changing one type to another,
My uses cases have nothing to do with that.
Is just that, in all the contexts where you have a "nullable proxy",
such as a pointer, an iterator, an optional, etc... the idiom
corresponding to "get the value or a default" is very common, so much
that a general utility to do that is IMO very useful.

> While not a perfect replacement, I tend to use (foo ? *foo : make_value()),
> as I usually don't want to pay the cost for make_value().

That is a totally valid alternative, but, as have been noticed, it's
only possible when you have an lvalue.
If you don't, then you just can't do that, and a separate form is *needed*

> Plus, I don't
> have to worry that other types might or (in all likelihood) might not
> overload get_value_or().


OK. Why would you have to worry about that?

>  This differs from begin(), end() and swap(),
> because they already have definitions that take care of 90+% of the cases.
>
>>
>> It is true that this decision makes a certain commitment to a
>> signature and expected semantics on the std namespace, but for this
>>
>> particular case I don't see that as a problem.
>
>
> Are you expecting people to overload this in namespace std?

No.

>
> To summarize:  I don't find this to be a useful customization point

See my next response to Vladimir for details on what I had in mind.

, because
> I'm not seeing a use case for a context where someone is changing an
> optional<T> to some other type (either explicitly or in generic code) and
> expecting the rest of their code to "just work".
>
Neither do I FWIW.

Best

--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com

--




.


Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Fri, 28 Dec 2012 13:33:00 -0300
Raw View
On Thu, Dec 27, 2012 at 8:26 PM, Vladimir Batov <vb.mail.247@gmail.com> wrote:
> On Friday, December 28, 2012 8:52:42 AM UTC+11, Nevin ":-)" Liber wrote:
>
> I do understand the potential usefulness of the function. Still I can't help
> thinking if trying so hard to find a place for it is really worth it. I feel
> one way or the other (free or member function) it'll be hardly used as I
> expect the ?: to be the preference by far. And if I remember correctly quite
> a few optional-related APIs have been dismissed exactly for the reason they
> were expected to be used very rarely. Well, at least it was the official
> line. ;-) Neither adding to the std namespace for potential/unproven
> extension nor adding to the optional api even though optional itself does
> not need it seem like clear winners.
>

OK. I concluded that we better do what Andrzej said and make it a member.

Here is the whole analysis FWIW.

I truly think that C++ would greatly benefit for a dedicated way to
retrieve the value of an nullable proxy object or a default value if
none exist.
However, something like that is not as trivial as it might seem. That
is the reason we propose something that is specific to
std::optional<>.

Following my Boost.Optional design I thought that std::optional<>
could "lead the way" into such an utility by providing a form of it
that would be eventually extended into the rest of the library.
That is, I imagined that, by naturally following the case of optional,
there would be:

template<class T>
T get_value_or( T const* p, T d  ) { return p ? *p : d ; }

template<class T>
T get_value_or( std::shared_ptr<T const> const& p, T d  ) { return p ?
*p : d ; }

template<class T>
T get_value_or( some_container_const_iterator<T> const& p, T d  ) {
return p ? *p : d ; }

etc, etc...

I realize now that something like that would never happen unless there
is a proposal to it,  and if such a proposal is made, it better be
cross-utility (that is, specifying the overloads and specializations
for all existing nullable-proxy types), but then, *that* proposal
would handle the case of std::optional<> along all the other cases,
hence it doesn't need to be in the optional proposal.

Having said that, we do need it in the API because you cannot use
operator ? without an lvalue (and lots of people, like me in fact,
avoid lvalues whenever possible)

Once I start thinking about a separate proposal that works on all
nullable-proxy types, I realize that I might prefer a core solution,
such as an operator ?? as there is in C# (in ruby we have ||) (all for
exactly this purpose), since, being in the core language it can better
avoid copies and temporaries.


BTW, Boost.Optional contains both a free function and a member
get_value_or. Google search reveals that the member version is used a
lot (in the many many expressions where the optional is an rvalue)


Best

--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com

--




.


Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Fri, 28 Dec 2012 13:45:21 -0300
Raw View
On Fri, Dec 28, 2012 at 1:33 PM, Fernando Cacciola
<fernando.cacciola@gmail.com> wrote:

> operator ?? as there is in C# (in ruby we have ||)

I inserted Ruby's operator || in an existing sentence and I realize
now it might be misleading.

That is of course the logical OR operator.

Is just that in Ruby all variables are internally pointers so all
variables are "nullable-proxies", i.e. they can all be nil
Then "obj || d" directly evaluates obj, yielding itself if it is not
nil, or nil otherwise, which default converts to boolean false, hence
evaluating "d" in that case.

Best

--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com

--




.


Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Fri, 28 Dec 2012 18:28:35 +0100
Raw View
On Fri, Dec 28, 2012 at 5:33 PM, Fernando Cacciola
<fernando.cacciola@gmail.com> wrote:
> Once I start thinking about a separate proposal that works on all
> nullable-proxy types, I realize that I might prefer a core solution,
> such as an operator ?? as there is in C# (in ruby we have ||) (all for
> exactly this purpose), since, being in the core language it can better
> avoid copies and temporaries.

Such an operator sounds great.

There's still the issue of what to return: a value or a reference.

void f(const string&);
optional<string> g();

f(g().get_value_or(""));

This does an extra move (or copy if string doesn't support moves), doesn't it?
Why can't get_value_or return a reference?
I understand the danger of dangling references, but I don't think
never returning references isn't the right answer.




--
Olaf

--




.


Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Fri, 28 Dec 2012 12:44:18 -0800 (PST)
Raw View
------=_Part_328_18320235.1356727458843
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable



W dniu pi=B1tek, 28 grudnia 2012 18:28:35 UTC+1 u=BFytkownik Olaf van der S=
pek=20
napisa=B3:
>
> On Fri, Dec 28, 2012 at 5:33 PM, Fernando Cacciola=20
> <fernando...@gmail.com <javascript:>> wrote:=20
> > Once I start thinking about a separate proposal that works on all=20
> > nullable-proxy types, I realize that I might prefer a core solution,=20
> > such as an operator ?? as there is in C# (in ruby we have ||) (all for=
=20
> > exactly this purpose), since, being in the core language it can better=
=20
> > avoid copies and temporaries.=20
>
> Such an operator sounds great.=20
>
> There's still the issue of what to return: a value or a reference.=20
>
> void f(const string&);=20
> optional<string> g();=20
>
> f(g().get_value_or(""));=20
>
> This does an extra move (or copy if string doesn't support moves), doesn'=
t=20
> it?=20
> Why can't get_value_or return a reference?=20
> I understand the danger of dangling references, but I don't think=20
> never returning references isn't the right answer.=20
>

This would require, I guess, the definition of the following three member=
=20
functions:

template <typename V>
auto get_value_or(U && v) && -> decltype(true? *std::move(*this) : std::
forward<U>(v));

template <typename V>
auto get_value_or(U && v) const& -> decltype(true? **this : std::forward<U>=
(
v));

template <typename V>
auto get_value_or(U && v) & -> decltype(true? **this : std::forward<U>(v));

Anyone else has an opinion?=20

Regards,
&rzej

--=20




------=_Part_328_18320235.1356727458843
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

<br><br>W dniu pi=B1tek, 28 grudnia 2012 18:28:35 UTC+1 u=BFytkownik Olaf v=
an der Spek napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Fri, =
Dec 28, 2012 at 5:33 PM, Fernando Cacciola
<br>&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
AfCyzg12uMMJ">fernando...@gmail.com</a>&gt; wrote:
<br>&gt; Once I start thinking about a separate proposal that works on all
<br>&gt; nullable-proxy types, I realize that I might prefer a core solutio=
n,
<br>&gt; such as an operator ?? as there is in C# (in ruby we have ||) (all=
 for
<br>&gt; exactly this purpose), since, being in the core language it can be=
tter
<br>&gt; avoid copies and temporaries.
<br>
<br>Such an operator sounds great.
<br>
<br>There's still the issue of what to return: a value or a reference.
<br>
<br>void f(const string&amp;);
<br>optional&lt;string&gt; g();
<br>
<br>f(g().get_value_or(""));
<br>
<br>This does an extra move (or copy if string doesn't support moves), does=
n't it?
<br>Why can't get_value_or return a reference?
<br>I understand the danger of dangling references, but I don't think
<br>never returning references isn't the right answer.
<br></blockquote><div><br>This would require, I guess, the definition of th=
e following three member functions:<br><br><div class=3D"prettyprint" 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 clas=
s=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;=
" class=3D"styled-by-prettify">template</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">typename</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> V</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r></span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> get_value_or<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">U </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> v</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">&amp;&amp;</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">-&gt;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">de=
cltype</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">true</span><s=
pan 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">std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">move</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(*</span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">this</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</s=
pan><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"> 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;" cl=
ass=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">U</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">&gt;(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">v</span><span style=3D"color: #660;" class=3D"styled-by-prettify">))=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br><=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">template</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> V</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> get_value_or</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">U </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">&amp;&amp;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> v</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">const</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&amp;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">-&gt;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">decltype</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">true</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">?</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: #008;" class=3D"styled-by-prettify">this</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: #0=
00;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">forward</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">U</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">&gt;(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">v</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">));</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">template</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color:=
 #008;" class=3D"styled-by-prettify">typename</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> V</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> get_value_or</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">U </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;=
&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> v</s=
pan><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">&amp;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">-&gt;</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">decltype</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">true</span><span style=3D"color: #660;" class=3D"styled-by-prettify">?=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">**</span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">this</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"> std</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">forward</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>U</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">v</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">));</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></code></di=
v><br>Anyone else has an opinion? <br><br>Regards,<br>&amp;rzej<br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_328_18320235.1356727458843--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Fri, 28 Dec 2012 14:49:33 -0600
Raw View
--bcaec550b336681fe904d1efcfb5
Content-Type: text/plain; charset=ISO-8859-13
Content-Transfer-Encoding: quoted-printable

On 28 December 2012 14:44, Andrzej Krzemie=F1ski <akrzemi1@gmail.com> wrote=
:

> This would require, I guess, the definition of the following three member
> functions:
>
> template <typename V>
> auto get_value_or(U && v) && -> decltype(true? *std::move(*this) : std::
> forward<U>(v));
>
> template <typename V>
> auto get_value_or(U && v) const& -> decltype(true? **this : std::forward<=
U
> >(v));
>
> template <typename V>
> auto get_value_or(U && v) & -> decltype(true? **this : std::forward<U>(v
> ));
>
> Anyone else has an opinion?
>

-1.  It should be obvious to users what get_value_or returns; otherwise, it
is an expert-only feature.
--=20
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--=20




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

On 28 December 2012 14:44, Andrzej Krzemie=C5=84ski <span dir=3D"ltr">&lt;<=
a href=3D"mailto:akrzemi1@gmail.com" target=3D"_blank">akrzemi1@gmail.com</=
a>&gt;</span> wrote:<br><div class=3D"gmail_quote"><blockquote class=3D"gma=
il_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-lef=
t:1ex">

<div>This would require, I guess, the definition of the following three mem=
ber functions:<br><br><div style=3D"background-color:rgb(250,250,250);borde=
r-color:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:brea=
k-word">

<code><div><span style=3D"color:#008">template</span><span style> </span><s=
pan style=3D"color:#660">&lt;</span><span style=3D"color:#008">typename</sp=
an><span style> V</span><span style=3D"color:#660">&gt;</span><span style><=
br>
</span><span style=3D"color:#008">auto</span><span style> get_value_or</spa=
n><span style=3D"color:#660">(</span><span style>U </span><span style=3D"co=
lor:#660">&amp;&amp;</span><span style> v</span><span style=3D"color:#660">=
)</span><span style> </span><span style=3D"color:#660">&amp;&amp;</span><sp=
an style> </span><span style=3D"color:#660">-&gt;</span><span style> </span=
><span style=3D"color:#008">decltype</span><span style=3D"color:#660">(</sp=
an><span style=3D"color:#008">true</span><span style=3D"color:#660">?</span=
><span style> </span><span style=3D"color:#660">*</span><span style>std</sp=
an><span style=3D"color:#660">::</span><span style>move</span><span style=
=3D"color:#660">(*</span><span style=3D"color:#008">this</span><span style=
=3D"color:#660">)</span><span style> </span><span style=3D"color:#660">:</s=
pan><span style> std</span><span style=3D"color:#660">::</span><span style>=
forward</span><span style=3D"color:#660">&lt;</span><span style>U</span><sp=
an style=3D"color:#660">&gt;(</span><span style>v</span><span style=3D"colo=
r:#660">));</span><span style><br>

<br></span><span style=3D"color:#008">template</span><span style> </span><s=
pan style=3D"color:#660">&lt;</span><span style=3D"color:#008">typename</sp=
an><span style> V</span><span style=3D"color:#660">&gt;</span><span style><=
br>
</span><span style=3D"color:#008">auto</span><span style> get_value_or</spa=
n><span style=3D"color:#660">(</span><span style>U </span><span style=3D"co=
lor:#660">&amp;&amp;</span><span style> v</span><span style=3D"color:#660">=
)</span><span style> </span><span style=3D"color:#008">const</span><span st=
yle=3D"color:#660">&amp;</span><span style> </span><span style=3D"color:#66=
0">-&gt;</span><span style> </span><span style=3D"color:#008">decltype</spa=
n><span style=3D"color:#660">(</span><span style=3D"color:#008">true</span>=
<span style=3D"color:#660">?</span><span style> </span><span style=3D"color=
:#660">**</span><span style=3D"color:#008">this</span><span style> </span><=
span style=3D"color:#660">:</span><span style> std</span><span style=3D"col=
or:#660">::</span><span style>forward</span><span style=3D"color:#660">&lt;=
</span><span style>U</span><span style=3D"color:#660">&gt;(</span><span sty=
le>v</span><span style=3D"color:#660">));</span><span style><br>

<br></span><span style=3D"color:#008">template</span><span style> </span><s=
pan style=3D"color:#660">&lt;</span><span style=3D"color:#008">typename</sp=
an><span style> V</span><span style=3D"color:#660">&gt;</span><span style><=
br>
</span><span style=3D"color:#008">auto</span><span style> get_value_or</spa=
n><span style=3D"color:#660">(</span><span style>U </span><span style=3D"co=
lor:#660">&amp;&amp;</span><span style> v</span><span style=3D"color:#660">=
)</span><span style> </span><span style=3D"color:#660">&amp;</span><span st=
yle> </span><span style=3D"color:#660">-&gt;</span><span style> </span><spa=
n style=3D"color:#008">decltype</span><span style=3D"color:#660">(</span><s=
pan style=3D"color:#008">true</span><span style=3D"color:#660">?</span><spa=
n style> </span><span style=3D"color:#660">**</span><span style=3D"color:#0=
08">this</span><span style> </span><span style=3D"color:#660">:</span><span=
 style> std</span><span style=3D"color:#660">::</span><span style>forward</=
span><span style=3D"color:#660">&lt;</span><span style>U</span><span style=
=3D"color:#660">&gt;(</span><span style>v</span><span style=3D"color:#660">=
));</span><span style><br>

</span></div></code></div><br>Anyone else has an opinion?=C2=A0</div></bloc=
kquote><div><br></div><div>-1. =C2=A0It should be obvious to users what get=
_value_or returns; otherwise, it is an expert-only feature.=C2=A0</div></di=
v>-- <br>=C2=A0Nevin &quot;:-)&quot; Liber=C2=A0 &lt;mailto:<a href=3D"mail=
to:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a>&gt;=
=C2=A0 (847) 691-1404

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--bcaec550b336681fe904d1efcfb5--

.


Author: Roman Perepelitsa <roman.perepelitsa@gmail.com>
Date: Fri, 28 Dec 2012 21:54:47 +0100
Raw View
--e89a8f3b9c81e6037804d1efe034
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

2012/12/28 Nevin Liber <nevin@eviloverlord.com>

> On 28 December 2012 14:44, Andrzej Krzemie=C5=84ski <akrzemi1@gmail.com> =
wrote:
>
>> This would require, I guess, the definition of the following three membe=
r
>> functions:
>>
>> template <typename V>
>> auto get_value_or(U && v) && -> decltype(true? *std::move(*this) : std::
>> forward<U>(v));
>>
>> template <typename V>
>> auto get_value_or(U && v) const& -> decltype(true? **this : std::forward=
<
>> U>(v));
>>
>> template <typename V>
>> auto get_value_or(U && v) & -> decltype(true? **this : std::forward<U>(v
>> ));
>>
>> Anyone else has an opinion?
>>
>
> -1.  It should be obvious to users what get_value_or returns; otherwise,
> it is an expert-only feature.
>

It returns opt ? *opt : default. Plain and simple.

Roman Perepelitsa.

--=20




--e89a8f3b9c81e6037804d1efe034
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

2012/12/28 Nevin Liber <span dir=3D"ltr">&lt;<a href=3D"mailto:nevin@evilov=
erlord.com" target=3D"_blank">nevin@eviloverlord.com</a>&gt;</span><br><div=
 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 class=3D"im">On 28 December 2012 14:44, Andrzej Krzemie=F1ski <span di=
r=3D"ltr">&lt;<a href=3D"mailto:akrzemi1@gmail.com" target=3D"_blank">akrze=
mi1@gmail.com</a>&gt;</span> wrote:<br></div><div class=3D"gmail_quote"><di=
v class=3D"im">

<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">

<div>This would require, I guess, the definition of the following three mem=
ber functions:<br><br><div style=3D"background-color:rgb(250,250,250);borde=
r-color:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:brea=
k-word">



<code><div><span style=3D"color:#008">template</span><span> </span><span st=
yle=3D"color:#660">&lt;</span><span style=3D"color:#008">typename</span><sp=
an> V</span><span style=3D"color:#660">&gt;</span><span><br>
</span><span style=3D"color:#008">auto</span><span> get_value_or</span><spa=
n style=3D"color:#660">(</span><span>U </span><span style=3D"color:#660">&a=
mp;&amp;</span><span> v</span><span style=3D"color:#660">)</span><span> </s=
pan><span style=3D"color:#660">&amp;&amp;</span><span> </span><span style=
=3D"color:#660">-&gt;</span><span> </span><span style=3D"color:#008">declty=
pe</span><span style=3D"color:#660">(</span><span style=3D"color:#008">true=
</span><span style=3D"color:#660">?</span><span> </span><span style=3D"colo=
r:#660">*</span><span>std</span><span style=3D"color:#660">::</span><span>m=
ove</span><span style=3D"color:#660">(*</span><span style=3D"color:#008">th=
is</span><span style=3D"color:#660">)</span><span> </span><span style=3D"co=
lor:#660">:</span><span> std</span><span style=3D"color:#660">::</span><spa=
n>forward</span><span style=3D"color:#660">&lt;</span><span>U</span><span s=
tyle=3D"color:#660">&gt;(</span><span>v</span><span style=3D"color:#660">))=
;</span><span><br>



<br></span><span style=3D"color:#008">template</span><span> </span><span st=
yle=3D"color:#660">&lt;</span><span style=3D"color:#008">typename</span><sp=
an> V</span><span style=3D"color:#660">&gt;</span><span><br>
</span><span style=3D"color:#008">auto</span><span> get_value_or</span><spa=
n style=3D"color:#660">(</span><span>U </span><span style=3D"color:#660">&a=
mp;&amp;</span><span> v</span><span style=3D"color:#660">)</span><span> </s=
pan><span style=3D"color:#008">const</span><span style=3D"color:#660">&amp;=
</span><span> </span><span style=3D"color:#660">-&gt;</span><span> </span><=
span style=3D"color:#008">decltype</span><span style=3D"color:#660">(</span=
><span style=3D"color:#008">true</span><span style=3D"color:#660">?</span><=
span> </span><span style=3D"color:#660">**</span><span style=3D"color:#008"=
>this</span><span> </span><span style=3D"color:#660">:</span><span> std</sp=
an><span style=3D"color:#660">::</span><span>forward</span><span style=3D"c=
olor:#660">&lt;</span><span>U</span><span style=3D"color:#660">&gt;(</span>=
<span>v</span><span style=3D"color:#660">));</span><span><br>



<br></span><span style=3D"color:#008">template</span><span> </span><span st=
yle=3D"color:#660">&lt;</span><span style=3D"color:#008">typename</span><sp=
an> V</span><span style=3D"color:#660">&gt;</span><span><br>
</span><span style=3D"color:#008">auto</span><span> get_value_or</span><spa=
n style=3D"color:#660">(</span><span>U </span><span style=3D"color:#660">&a=
mp;&amp;</span><span> v</span><span style=3D"color:#660">)</span><span> </s=
pan><span style=3D"color:#660">&amp;</span><span> </span><span style=3D"col=
or:#660">-&gt;</span><span> </span><span style=3D"color:#008">decltype</spa=
n><span style=3D"color:#660">(</span><span style=3D"color:#008">true</span>=
<span style=3D"color:#660">?</span><span> </span><span style=3D"color:#660"=
>**</span><span style=3D"color:#008">this</span><span> </span><span style=
=3D"color:#660">:</span><span> std</span><span style=3D"color:#660">::</spa=
n><span>forward</span><span style=3D"color:#660">&lt;</span><span>U</span><=
span style=3D"color:#660">&gt;(</span><span>v</span><span style=3D"color:#6=
60">));</span><span><br>



</span></div></code></div><br>Anyone else has an opinion?=A0</div></blockqu=
ote><div><br></div></div><div>-1. =A0It should be obvious to users what get=
_value_or returns; otherwise, it is an expert-only feature.</div></div></bl=
ockquote>

<div><br></div><div>It returns <font face=3D"courier new, monospace">opt ? =
*opt : default</font>. Plain and simple.</div><div><br></div><div>Roman Per=
epelitsa.=A0</div></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--e89a8f3b9c81e6037804d1efe034--

.


Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Fri, 28 Dec 2012 12:55:46 -0800 (PST)
Raw View
------=_Part_354_25436285.1356728146187
Content-Type: text/plain; charset=ISO-8859-1



> This would require, I guess, the definition of the following three member
> functions:
>
> template <typename V>
> auto get_value_or(U && v) && -> decltype(true? *std::move(*this) : std::
> forward<U>(v));
>
> template <typename V>
> auto get_value_or(U && v) const& -> decltype(true? **this : std::forward<U
> >(v));
>
> template <typename V>
> auto get_value_or(U && v) & -> decltype(true? **this : std::forward<U>(v
> ));
>
> Now I wonder if Optional for performance reasons shouldn't have an rvalue
reference overload for accessing the contained value:

T&& operator*() &&;

The usage contexts may look unsafe: you get the contained value w/o
checking for optional being engaged, but it makes sense in contexts, where
we know it will always be engaged, but the type-system requires that we
operate on optionals.

Regards,
&rzej

--




------=_Part_354_25436285.1356728146187
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;"><div>This would require, I=
 guess, the definition of the following three member functions:<br><br><div=
 style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);b=
order-style:solid;border-width:1px;word-wrap:break-word"><code><div><span s=
tyle=3D"color:#008">template</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">&lt;</span><span style=3D"color:#008">typename</span>=
<span style=3D"color:#000"> V</span><span style=3D"color:#660">&gt;</span><=
span style=3D"color:#000"><br></span><span style=3D"color:#008">auto</span>=
<span style=3D"color:#000"> get_value_or</span><span style=3D"color:#660">(=
</span><span style=3D"color:#000">U </span><span style=3D"color:#660">&amp;=
&amp;</span><span style=3D"color:#000"> v</span><span style=3D"color:#660">=
)</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&amp;=
&amp;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">-=
&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#008">de=
cltype</span><span style=3D"color:#660">(</span><span style=3D"color:#008">=
true</span><span style=3D"color:#660">?</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">*</span><span style=3D"color:#000">std</sp=
an><span style=3D"color:#660">::</span><span style=3D"color:#000">move</spa=
n><span style=3D"color:#660">(*</span><span style=3D"color:#008">this</span=
><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#660">:</span><span style=3D"color:#000"> std</span><span =
style=3D"color:#660">::</span><span style=3D"color:#000">forward</span><spa=
n style=3D"color:#660">&lt;</span><span style=3D"color:#000">U</span><span =
style=3D"color:#660">&gt;(</span><span style=3D"color:#000">v</span><span s=
tyle=3D"color:#660">));</span><span style=3D"color:#000"><br><br></span><sp=
an style=3D"color:#008">template</span><span style=3D"color:#000"> </span><=
span style=3D"color:#660">&lt;</span><span style=3D"color:#008">typename</s=
pan><span style=3D"color:#000"> V</span><span style=3D"color:#660">&gt;</sp=
an><span style=3D"color:#000"><br></span><span style=3D"color:#008">auto</s=
pan><span style=3D"color:#000"> get_value_or</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#000">U </span><span style=3D"color:#660">&=
amp;&amp;</span><span style=3D"color:#000"> v</span><span style=3D"color:#6=
60">)</span><span style=3D"color:#000"> </span><span style=3D"color:#008">c=
onst</span><span style=3D"color:#660">&amp;</span><span style=3D"color:#000=
"> </span><span style=3D"color:#660">-&gt;</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">decltype</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#008">true</span><span style=3D"color:#660"=
>?</span><span style=3D"color:#000"> </span><span style=3D"color:#660">**</=
span><span style=3D"color:#008">this</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#660">:</span><span style=3D"color:#000"> std</span=
><span style=3D"color:#660">::</span><span style=3D"color:#000">forward</sp=
an><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">U</span=
><span style=3D"color:#660">&gt;(</span><span style=3D"color:#000">v</span>=
<span style=3D"color:#660">));</span><span style=3D"color:#000"><br><br></s=
pan><span style=3D"color:#008">template</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">type=
name</span><span style=3D"color:#000"> V</span><span style=3D"color:#660">&=
gt;</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">=
auto</span><span style=3D"color:#000"> get_value_or</span><span style=3D"co=
lor:#660">(</span><span style=3D"color:#000">U </span><span style=3D"color:=
#660">&amp;&amp;</span><span style=3D"color:#000"> v</span><span style=3D"c=
olor:#660">)</span><span style=3D"color:#000"> </span><span style=3D"color:=
#660">&amp;</span><span style=3D"color:#000"> </span><span style=3D"color:#=
660">-&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#0=
08">decltype</span><span style=3D"color:#660">(</span><span style=3D"color:=
#008">true</span><span style=3D"color:#660">?</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#660">**</span><span style=3D"color:#008">=
this</span><span style=3D"color:#000"> </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">forward</span><span style=3D"color:#660">&l=
t;</span><span style=3D"color:#000">U</span><span style=3D"color:#660">&gt;=
(</span><span style=3D"color:#000">v</span><span style=3D"color:#660">));</=
span><span style=3D"color:#000"><br></span></div></code></div><br></div></b=
lockquote><div>Now I wonder if Optional for performance reasons shouldn't h=
ave an rvalue reference overload for accessing the contained value:<br><br>=
<div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); b=
order-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; wo=
rd-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettypr=
int"><span style=3D"color: #000;" class=3D"styled-by-prettify">T</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">operator</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">*()</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">&amp;&amp;;</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br></span></div></code></div><br>The usage=
 contexts may look unsafe: you get the contained value w/o checking for opt=
ional being engaged, but it makes sense in contexts, where we know it will =
always be engaged, but the type-system requires that we operate on optional=
s.<br><br>Regards,<br>&amp;rzej<br><br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_354_25436285.1356728146187--

.


Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Fri, 28 Dec 2012 18:02:20 -0300
Raw View
On Fri, Dec 28, 2012 at 5:49 PM, Nevin Liber <nevin@eviloverlord.com> wrote=
:
> On 28 December 2012 14:44, Andrzej Krzemie=F1ski <akrzemi1@gmail.com> wro=
te:
>>
>> This would require, I guess, the definition of the following three membe=
r
>> functions:
>>
>> template <typename V>
>> auto get_value_or(U && v) && -> decltype(true? *std::move(*this) :
>> std::forward<U>(v));
>>
>> template <typename V>
>> auto get_value_or(U && v) const& -> decltype(true? **this :
>> std::forward<U>(v));
>>
>> template <typename V>
>> auto get_value_or(U && v) & -> decltype(true? **this :
>> std::forward<U>(v));
>>
>> Anyone else has an opinion?
>
>
> -1.  It should be obvious to users what get_value_or returns; otherwise, =
it
> is an expert-only feature.

I agree.

Which is why in the end I accepted that it better returns a (copy of
the) value (which is unlike Boost.Optional)
That's the most obvious and safe approach.


--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com

--=20




.


Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Fri, 28 Dec 2012 18:10:58 -0300
Raw View
On Fri, Dec 28, 2012 at 5:54 PM, Roman Perepelitsa
<roman.perepelitsa@gmail.com> wrote:
>>
>> -1.  It should be obvious to users what get_value_or returns; otherwise,
>> it is an expert-only feature.
>
>
> It returns opt ? *opt : default.


> Plain and simple.
>

Ah, but it isn't... that's the subtlety here.

* opt returns a reference, not a value (and it shouldn't return a value)

by default has a type that depends on the actual call expression.
It can be const& or &&

If it is const& then we can return a const& as well, as in
If it is && we must return a value.

It is possible to have overloads for one and another type of default,
but then the result would be a reference to the optional internally
held OR a copy of it depending solely on the type of the default. That
IMO is a reciept for disaster.

--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com

--




.


Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Fri, 28 Dec 2012 18:25:10 -0300
Raw View
Btw, I mentioned this when we first discussed it here, but just in
case is not evident now.

When default is temporary, we cannot return const& because that
temporary *will* be destroyed at the end of the expression:

We could think of a mechanism that moves such temporary into the
result, which is what Andrzej seems to be considering right now (in
his last post), but IMO we still have the usability problem that we'd
get a reference to the contained value or a (move to) value depending
on how we passed the default. I'm not fond of that so I'd leave the
by-value result, for simplicity


--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com

--




.


Author: Vladimir Batov <vb.mail.247@gmail.com>
Date: Fri, 28 Dec 2012 16:35:25 -0800 (PST)
Raw View
------=_Part_382_25878641.1356741325569
Content-Type: text/plain; charset=ISO-8859-1

Fernando,

Thank you for taking time to explain it in the post below and the follow-up
posts. It's much appreciated. It all makes sense. Indeed get_value_or
caters for subtle cases where ?: might not do. And in that light I find
your original std::get_value_or suggestion cleaner architecturally. Still,
you, guys, have invested immencely more time thinking about it. So,
ultimately it's your choice that matters.

Best,
V.

On Saturday, December 29, 2012 3:33:00 AM UTC+11, Fernando Cacciola wrote:
>
> > On Thu, Dec 27, 2012 at 8:26 PM, Vladimir Batov <vb.ma...@gmail.com<javascript:>>
> wrote:
> >
> > I do understand the potential usefulness of the function. Still I can't
> help
> > thinking if trying so hard to find a place for it is really worth it...
>
> OK. I concluded that we better do what Andrzej said and make it a member.
>
> Here is the whole analysis FWIW.
>
> I truly think that C++ would greatly benefit for a dedicated way to
> retrieve the value of an nullable proxy object or a default value if
> none exist.
> However, something like that is not as trivial as it might seem. That
> is the reason we propose something that is specific to
> std::optional<>.
>
> Following my Boost.Optional design I thought that std::optional<>
> could "lead the way" into such an utility by providing a form of it
> that would be eventually extended into the rest of the library.
> That is, I imagined that, by naturally following the case of optional,
> there would be:
>
> template<class T>
> T get_value_or( T const* p, T d  ) { return p ? *p : d ; }
>
> template<class T>
> T get_value_or( std::shared_ptr<T const> const& p, T d  ) { return p ?
> *p : d ; }
>
> template<class T>
> T get_value_or( some_container_const_iterator<T> const& p, T d  ) {
> return p ? *p : d ; }
>
> etc, etc...
>
> I realize now that something like that would never happen unless there
> is a proposal to it,  and if such a proposal is made, it better be
> cross-utility (that is, specifying the overloads and specializations
> for all existing nullable-proxy types), but then, *that* proposal
> would handle the case of std::optional<> along all the other cases,
> hence it doesn't need to be in the optional proposal.
>
> Having said that, we do need it in the API because you cannot use
> operator ? without an lvalue (and lots of people, like me in fact,
> avoid lvalues whenever possible)
>
> Once I start thinking about a separate proposal that works on all
> nullable-proxy types, I realize that I might prefer a core solution,
> such as an operator ?? as there is in C# (in ruby we have ||) (all for
> exactly this purpose), since, being in the core language it can better
> avoid copies and temporaries.
>
> BTW, Boost.Optional contains both a free function and a member
> get_value_or. Google search reveals that the member version is used a
> lot (in the many many expressions where the optional is an rvalue)
>
>

--




------=_Part_382_25878641.1356741325569
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Fernando, <br><br>Thank you for taking time to explain it in the post below=
 and the follow-up posts. It's much appreciated. It all makes sense. Indeed=
 get_value_or caters for subtle cases where ?: might not do. And in that li=
ght I find your original std::get_value_or suggestion cleaner architectural=
ly. Still, you, guys, have invested immencely more time thinking about it. =
So, ultimately it's your choice that matters.<br><br>Best,<br>V.<br><br>On =
Saturday, December 29, 2012 3:33:00 AM UTC+11, Fernando Cacciola wrote:<blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;">&gt; On Thu, Dec 27, 2012 at 8:26 =
PM, Vladimir Batov &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfusc=
ated-mailto=3D"DibVeHwAIA0J">vb.ma...@gmail.com</a>&gt; wrote:
<br>&gt;
<br>&gt; I do understand the potential usefulness of the function. Still I =
can't help
<br>&gt; thinking if trying so hard to find a place for it is really worth =
it...<br><br>OK. I concluded that we better do what Andrzej said and make i=
t a member.
<br>
<br>Here is the whole analysis FWIW.
<br>
<br>I truly think that C++ would greatly benefit for a dedicated way to
<br>retrieve the value of an nullable proxy object or a default value if
<br>none exist.
<br>However, something like that is not as trivial as it might seem. That
<br>is the reason we propose something that is specific to
<br>std::optional&lt;&gt;.
<br>
<br>Following my Boost.Optional design I thought that std::optional&lt;&gt;
<br>could "lead the way" into such an utility by providing a form of it
<br>that would be eventually extended into the rest of the library.
<br>That is, I imagined that, by naturally following the case of optional,
<br>there would be:
<br>
<br>template&lt;class T&gt;
<br>T get_value_or( T const* p, T d &nbsp;) { return p ? *p : d ; }
<br>
<br>template&lt;class T&gt;
<br>T get_value_or( std::shared_ptr&lt;T const&gt; const&amp; p, T d &nbsp;=
) { return p ?
<br>*p : d ; }
<br>
<br>template&lt;class T&gt;
<br>T get_value_or( some_container_const_iterator&lt;<wbr>T&gt; const&amp; =
p, T d &nbsp;) {
<br>return p ? *p : d ; }
<br>
<br>etc, etc...
<br>
<br>I realize now that something like that would never happen unless there
<br>is a proposal to it, &nbsp;and if such a proposal is made, it better be
<br>cross-utility (that is, specifying the overloads and specializations
<br>for all existing nullable-proxy types), but then, *that* proposal
<br>would handle the case of std::optional&lt;&gt; along all the other case=
s,
<br>hence it doesn't need to be in the optional proposal.
<br>
<br>Having said that, we do need it in the API because you cannot use
<br>operator ? without an lvalue (and lots of people, like me in fact,
<br>avoid lvalues whenever possible)
<br>
<br>Once I start thinking about a separate proposal that works on all
<br>nullable-proxy types, I realize that I might prefer a core solution,
<br>such as an operator ?? as there is in C# (in ruby we have ||) (all for
<br>exactly this purpose), since, being in the core language it can better
<br>avoid copies and temporaries.
<br>
<br>
BTW, Boost.Optional contains both a free function and a member
<br>get_value_or. Google search reveals that the member version is used a
<br>lot (in the many many expressions where the optional is an rvalue)
<br>
<br></blockquote>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_382_25878641.1356741325569--

.


Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Sat, 29 Dec 2012 17:29:12 +0100
Raw View
On Fri, Dec 28, 2012 at 10:25 PM, Fernando Cacciola
<fernando.cacciola@gmail.com> wrote:
> When default is temporary, we cannot return const& because that
> temporary *will* be destroyed at the end of the expression:

I don't follow, how's that a problem?
Returning the reference seems fine, storing it is the problem.

> We could think of a mechanism that moves such temporary into the
> result, which is what Andrzej seems to be considering right now (in
> his last post), but IMO we still have the usability problem that we'd
> get a reference to the contained value or a (move to) value depending
> on how we passed the default. I'm not fond of that so I'd leave the
> by-value result, for simplicity

That doesn't address the performance / unnecessary move/copy issue.
--
Olaf

--




.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Sat, 29 Dec 2012 12:04:00 -0600
Raw View
--0015175d07826d80d004d2019dbb
Content-Type: text/plain; charset=ISO-8859-1

On 29 December 2012 10:29, Olaf van der Spek <olafvdspek@gmail.com> wrote:

> > We could think of a mechanism that moves such temporary into the
> > result, which is what Andrzej seems to be considering right now (in
> > his last post), but IMO we still have the usability problem that we'd
> > get a reference to the contained value or a (move to) value depending
> > on how we passed the default. I'm not fond of that so I'd leave the
> > by-value result, for simplicity
>
> That doesn't address the performance / unnecessary move/copy issue.
>

Even if you fix that problem, how do you fix the performance / unnecessary
function/constructor call issue:

o.get_value_or(make_value()); // don't want to call make_value() when o is
engaged


Other than using the conditional operator, I don't see any way to address
all the potential micro-optimization performance issues.  If you care that
much about this micro-optimization, write it yourself, instead of trying to
standardize an expert-only interface.


I don't see how

o.get_value_or(v);
o.get_value_or(make_value());

returning two different things is teachable or useable.  I know I'd vote
against it.
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--




--0015175d07826d80d004d2019dbb
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On 29 December 2012 10:29, Olaf van der Spek <span dir=3D"ltr">&lt;<a href=
=3D"mailto:olafvdspek@gmail.com" target=3D"_blank">olafvdspek@gmail.com</a>=
&gt;</span> wrote:<br><div 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 class=3D"im">&gt; We could think of a mechanism that moves such tempor=
ary into the</div><div class=3D"im">
&gt; result, which is what Andrzej seems to be considering right now (in<br=
>
&gt; his last post), but IMO we still have the usability problem that we&#3=
9;d<br>
&gt; get a reference to the contained value or a (move to) value depending<=
br>
&gt; on how we passed the default. I&#39;m not fond of that so I&#39;d leav=
e the<br>
&gt; by-value result, for simplicity<br>
<br>
</div>That doesn&#39;t address the performance / unnecessary move/copy issu=
e.<br></blockquote><div><br></div><div>Even if you fix that problem, how do=
 you fix the performance / unnecessary function/constructor call issue:</di=
v>

<div><br></div><div>o.get_value_or(make_value()); // don&#39;t want to call=
 make_value() when o is engaged</div><div><br></div><div><br></div><div>Oth=
er than using the conditional operator, I don&#39;t see any way to address =
all the potential micro-optimization performance issues. =A0If you care tha=
t much about this micro-optimization, write it yourself, instead of trying =
to standardize an expert-only interface.</div>

<div><br></div><div><br></div><div>I don&#39;t see how</div><div><br></div>=
<div>o.get_value_or(v);</div><div>o.get_value_or(make_value());</div><div><=
br></div><div>returning two different things is teachable or useable. =A0I =
know I&#39;d vote against it.</div>

</div>-- <br>=A0Nevin &quot;:-)&quot; Liber=A0 &lt;mailto:<a href=3D"mailto=
:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a>&gt;=
=A0 (847) 691-1404

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--0015175d07826d80d004d2019dbb--

.


Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Sat, 29 Dec 2012 19:14:30 +0100
Raw View
On Sat, Dec 29, 2012 at 7:04 PM, Nevin Liber <nevin@eviloverlord.com> wrote:
>> That doesn't address the performance / unnecessary move/copy issue.
>
>
> Even if you fix that problem, how do you fix the performance / unnecessary
> function/constructor call issue:

You can't / don't.

> o.get_value_or(make_value()); // don't want to call make_value() when o is
> engaged
>
>
> Other than using the conditional operator, I don't see any way to address
> all the potential micro-optimization performance issues.  If you care that
> much about this micro-optimization, write it yourself, instead of trying to
> standardize an expert-only interface.
>
>
> I don't see how
>
> o.get_value_or(v);
> o.get_value_or(make_value());
>
> returning two different things is teachable or useable.  I know I'd vote
> against it.

How is it not teachable? Wouldn't the conditional operator 'return'
different things as well?
Why does it even need to return two different things? Both could
return a reference.

This seems equivalent to using string::c_str() on a temporary.

--
Olaf

--




.


Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Sat, 29 Dec 2012 16:33:00 -0300
Raw View
On Sat, Dec 29, 2012 at 1:29 PM, Olaf van der Spek <olafvdspek@gmail.com> wrote:
> On Fri, Dec 28, 2012 at 10:25 PM, Fernando Cacciola
> <fernando.cacciola@gmail.com> wrote:
>> When default is temporary, we cannot return const& because that
>> temporary *will* be destroyed at the end of the expression:
>
> I don't follow, how's that a problem?
> Returning the reference seems fine, storing it is the problem.
>

Imagine get_value_or where to return a const&

optional<string> o ;

string const& v = o.get_value_or( "default" ) ;

std::cout << v ; // This is UB. The temporary string was destroyed already


>> We could think of a mechanism that moves such temporary into the
>> result, which is what Andrzej seems to be considering right now (in
>> his last post), but IMO we still have the usability problem that we'd
>> get a reference to the contained value or a (move to) value depending
>> on how we passed the default. I'm not fond of that so I'd leave the
>> by-value result, for simplicity
>
> That doesn't address the performance / unnecessary move/copy issue.

No, but in the context where we cannot return a reference (for the
reason I shown above). it helps by moving as opposed to copying.

--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com

--




.


Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Sat, 29 Dec 2012 16:42:18 -0300
Raw View
On Sat, Dec 29, 2012 at 3:14 PM, Olaf van der Spek <olafvdspek@gmail.com> wrote:

> This seems equivalent to using string::c_str() on a temporary.

It is technically the same issue indeed, but the usage context is
entirely different.

In our case, passing a temporary to the default is the most common
case, specially temporaries of integral or floating type.

optional<int> o ;

o.get_value_or(-1);

that is a *very very* common IME.

Also (and I use this a lot), something like

optional<transformation> o ;

o.get_value_or( transformation::identity ) ;

in which case the UB would most likely result in a real problem.

Best

--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com

--




.


Author: Vladimir Batov <vb.mail.247@gmail.com>
Date: Sun, 30 Dec 2012 07:20:45 +1100
Raw View
>On Sun, Dec 30, 2012 at 6:42 AM, Fernando Cacciola <fernando.cacciola@gmail.com> wrote:
>> On Sat, Dec 29, 2012 at 3:14 PM, Olaf van der Spek <olafvdspek@gmail.com> wrote:
>> This seems equivalent to using string::c_str() on a temporary.
>
> It is technically the same issue indeed, but the usage context is
> entirely different.
>
> In our case, passing a temporary to the default is the most common
> case, specially temporaries of integral or floating type.
>
> optional<int> o ;
> o.get_value_or(-1);
>
> that is a *very very* common IME.

Indeed. However, for basic mainstream types the ?: works just fine

int r1 = o ? *o : -1;
int const& r2 = o ? *o : -1;

More so, it's efficient, immediately recognizable, quite obvious and
already available.

> Also (and I use this a lot), something like
> optional<transformation> o ;
> o.get_value_or( transformation::identity ) ;
> in which case the UB would most likely result in a real problem.

Again, just tried with Cygwin gcc 4.5.3 and the following works just
fine, with no problem, no overhead, no reliance on std::move and
subtle gotchas :

transformation const& res = o ? *o :
transformation::identity/*temporary created*/;

That still works (with gcc 4.3.5) with the style you are favoring
(i.e. avoiding lvalues... if I understand correctly):

void fun1(transformation);
void fun2(transformation const&);

fun1(o ? *o : transformation::identity);
fun2(o ? *o : transformation::identity);

What am I missing?

--




.


Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Sat, 29 Dec 2012 17:34:14 -0300
Raw View
On Sat, Dec 29, 2012 at 5:20 PM, Vladimir Batov <vb.mail.247@gmail.com> wrote:

> What am I missing?
>
That you can only use operator ? with an lvalue:

optional<int> get();

int const& v = get() ? get() : -1 ;

That won't work.

Now....

I've considered what I would call the perfect solution, which is to
the improve the rules for extending the life of a temporary (that is
why operator ? works)

That is, if the language specified that a temporary that is an
argument to a function, bound to the reference that is the parameter,
is returned from the function as is, then it's life extends beyond as
if it where directly bound to the reference that holds the function
result.
In that case, a function call would have the same effect on
temporaries like operator ? and we could use a single version taking
and returning const&

Unfortunately, this situation is what I call a "proposal deadlock". I
can't propose a feature that only makes since if a separate proposal
is accepted.
Granted, I could solve that race in the same way all races are solved,
by sequencing them, but I wouldn't hold the optional proposal for
that.

Best

--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com

--




.


Author: Vladimir Batov <vb.mail.247@gmail.com>
Date: Sun, 30 Dec 2012 08:51:40 +1100
Raw View
> On Sun, Dec 30, 2012 at 7:34 AM, Fernando Cacciola <fernando.cacciola@gmail.com> wrote:
>> On Sat, Dec 29, 2012 at 5:20 PM, Vladimir Batov <vb.mail.247@gmail.com> wrote:
>
>> What am I missing?
>>
> That you can only use operator ? with an lvalue:
>
> optional<int> get();
> int const& v = get() ? get() : -1 ;
>
> That won't work.

For clarity... it has a * with the second get(), right?

int const& v = get() ? *get() : -1 ;

My humble apologies... I can't test it right now... but, apart from
inefficiency, why that does not work? I do not expect any UB as the
named reference 'v' keeps the result of get() (the temporary) alive.

> I've considered what I would call the perfect solution, which is to
> the improve the rules for extending the life of a temporary (that is
> why operator ? works)
>
> That is, if the language specified that a temporary that is an
> argument to a function, bound to the reference that is the parameter,
> is returned from the function as is, then it's life extends beyond as
> if it where directly bound to the reference that holds the function
> result.

IMO that makes sense with or without optional. Pls forgive my
ignorance (or rather forgetfulness) but isn't it the case already?
Something is whispering into my ear that temporaries are destroyed at
end of full expression. That is, the following is safe:

std::string get();
void fun(char const*);

fun(get().c_str());

> In that case, a function call would have the same effect on
> temporaries like operator ? and we could use a single version taking
> and returning const&

Actually, if my memory serves me, it's not ?:'s special properties
that keep the temporary around. In case of

int const& r = ... temporary is created

it's the named reference 'r' that keeps the temporary around. In case of

fun(o ? *o : -1)

it's the full-expression rule (regarding temporaries) that I mentioned above.

> Unfortunately, this situation is what I call a "proposal deadlock". I
> can't propose a feature that only makes since if a separate proposal
> is accepted.
> Granted, I could solve that race in the same way all races are solved,
> by sequencing them, but I wouldn't hold the optional proposal for
> that.

--




.


Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Sat, 29 Dec 2012 19:13:27 -0300
Raw View
On Sat, Dec 29, 2012 at 6:51 PM, Vladimir Batov <vb.mail.247@gmail.com> wrote:
>> On Sun, Dec 30, 2012 at 7:34 AM, Fernando Cacciola <fernando.cacciola@gmail.com> wrote:
>>> On Sat, Dec 29, 2012 at 5:20 PM, Vladimir Batov <vb.mail.247@gmail.com> wrote:
>>
>>> What am I missing?
>>>
>> That you can only use operator ? with an lvalue:
>>
>> optional<int> get();
>> int const& v = get() ? get() : -1 ;
>>
>> That won't work.
>
> For clarity... it has a * with the second get(), right?
>
> int const& v = get() ? *get() : -1 ;
>
Right. I forgot the *

> My humble apologies... I can't test it right now... but, apart from
> inefficiency, why that does not work?

get() is called twice.
Not only is that potentially inefficient, there is no guarantee that
the value returned by the get() to the left of ? is the same as the
one to the right.

> I do not expect any UB as the
> named reference 'v' keeps the result of get() (the temporary) alive.
>
Right.
In this form the problem is not the lifetime of the result, is the
fact that there two different constructions, one for the

>> I've considered what I would call the perfect solution, which is to
>> the improve the rules for extending the life of a temporary (that is
>> why operator ? works)
>>
>> That is, if the language specified that a temporary that is an
>> argument to a function, bound to the reference that is the parameter,
>> is returned from the function as is, then it's life extends beyond as
>> if it where directly bound to the reference that holds the function
>> result.
>
> IMO that makes sense with or without optional. Pls forgive my
> ignorance (or rather forgetfulness) but isn't it the case already?

Unfortunately not.

> Something is whispering into my ear that temporaries are destroyed at
> end of full expression.

That is correct.

>That is, the following is safe:
>
> std::string get();
> void fun(char const*);
>
> fun(get().c_str());
>
Indeed. That's totally safe.

*inside* func the temporary is alive.

What is not OK is the following:

char const* fun( char const* p ) { return p ; }

char const* p = fun(get().c_str());

// AT THIS POINT p is dangling

And in fact, I'm pretty sure even this:

bar( fun(get().c_str()) ) ;

won't work, since AFAICT the full-expression that keeps the temporary
alive ends after the call to foo() completes, and it does not extend
to the call to bar.


>> In that case, a function call would have the same effect on
>> temporaries like operator ? and we could use a single version taking
>> and returning const&
>
> Actually, if my memory serves me, it's not ?:'s special properties
> that keep the temporary around. In case of
>
> int const& r = ... temporary is created
>
> it's the named reference 'r' that keeps the temporary around.

Yes.
But it works combined with the fact that the reference doing the trick
is the one holding "the result" of the operator.

If you have, OTOH,

int const& r = foo( temporary() ) ;

then the reference doing the trick is the parameter to foo(), not r'.
That's why I said that we need a way to relate the parameter reference
to the result reference so the keep-alive effect can mimic that of the
operator

>
> fun(o ? *o : -1)
>
> it's the full-expression rule (regarding temporaries) that I mentioned above.
>
Yes.

But what we need for the case of get_value_or is to get a grip of the
argument *after* the function call completed, which is where the full
expression ends.

That is all of course my understanding, and I would love to be wrong.
(FWIW is the understanding of VS2012 as I did test this back when we
first discussed it)

--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com

--




.


Author: Vladimir Batov <vb.mail.247@gmail.com>
Date: Sun, 30 Dec 2012 09:28:42 +1100
Raw View
> On Sun, Dec 30, 2012 at 9:13 AM, Fernando Cacciola <fernando.cacciola@gmail.com> wrote:
> On Sat, Dec 29, 2012 at 6:51 PM, Vladimir Batov <vb.mail.247@gmail.com> wrote:
>>> On Sun, Dec 30, 2012 at 7:34 AM, Fernando Cacciola <fernando.cacciola@gmail.com> wrote:
>>>> On Sat, Dec 29, 2012 at 5:20 PM, Vladimir Batov <vb.mail.247@gmail.com> wrote:
>>>
>>>> What am I missing?
>>>>
>>> That you can only use operator ? with an lvalue:
>>>
>>> optional<int> get();
>>> int const& v = get() ? get() : -1 ;
>>>
>>> That won't work.
>>
>> For clarity... it has a * with the second get(), right?
>>
>> int const& v = get() ? *get() : -1 ;
>>
> Right. I forgot the *
>
>> My humble apologies... I can't test it right now... but, apart from
>> inefficiency, why that does not work?
>
> get() is called twice.
> Not only is that potentially inefficient, there is no guarantee that
> the value returned by the get() to the left of ? is the same as the
> one to the right.
>
>> I do not expect any UB as the
>> named reference 'v' keeps the result of get() (the temporary) alive.
>>
> Right.
> In this form the problem is not the lifetime of the result, is the
> fact that there two different constructions, one for the
> ...

Apologies for cutting your reply short -- I have to be running but
want to address this particular point. We established that

int const& v = get() ? *get() : -1;

works but you are not happy with the "inefficiency", etc. of calling
get() twice. It's does not sound like an optional problem. You'll get
the same with any function:

int const& v = some_func() ? some_func() : -1;

And I suspect there is a simple solution to that. If one wants to
re-use something (a result of a function), that needs to be stored
(and re-used as many times as needed) with:

int const& r = some_func();
int const& v = r ? r : -1;

It seems (IMO of course) that trying to avoid having 'r' comes at a
too high a price. I certainly have nothing against you following your
particular style but (again) I am doubtful that such facility should
be given to the wider programming community as I suspect it'll cause
way more confusion than good. Again, IMO.

--




.


Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Sun, 30 Dec 2012 01:00:31 +0100
Raw View
On Sat, Dec 29, 2012 at 8:33 PM, Fernando Cacciola
<fernando.cacciola@gmail.com> wrote:
>> I don't follow, how's that a problem?
>> Returning the reference seems fine, storing it is the problem.
>>
>
> Imagine get_value_or where to return a const&
>
> optional<string> o ;
>
> string const& v = o.get_value_or( "default" ) ;
>
> std::cout << v ; // This is UB. The temporary string was destroyed already

Like I said, it's not the return type that's the problem but the type
of v. Why did you pick a reference?


On Sat, Dec 29, 2012 at 11:13 PM, Fernando Cacciola
<fernando.cacciola@gmail.com> wrote:
> What is not OK is the following:
>
> char const* fun( char const* p ) { return p ; }
>
> char const* p = fun(get().c_str());
>
> // AT THIS POINT p is dangling

Not necessarily, if get() returns a reference to a string that's still alive.

> And in fact, I'm pretty sure even this:
>
> bar( fun(get().c_str()) ) ;
>
> won't work, since AFAICT the full-expression that keeps the temporary
> alive ends after the call to foo() completes, and it does not extend
> to the call to bar.

Don't think you're right here. IIRC temporaries stay alive until the
sequence point (;).


--
Olaf

--




.


Author: =?UTF-8?Q?R=C3=B3bert_D=C3=A1vid?= <lrdxgm@gmail.com>
Date: Sat, 29 Dec 2012 16:25:04 -0800 (PST)
Raw View
------=_Part_480_6236755.1356827104120
Content-Type: text/plain; charset=ISO-8859-1


>
> Even if you fix that problem, how do you fix the performance / unnecessary
> function/constructor call issue:
>
> o.get_value_or(make_value()); // don't want to call make_value() when o is
> engaged
>
>
For this, how about an overload (or template specialization, or whatever)
that accepts a functor that returns an appropriate type?

o.get_value_or([]{ return make_value();});

Robert

--




------=_Part_480_6236755.1356827104120
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div class=3D"gmail_quote"><di=
v>Even if you fix that problem, how do you fix the performance / unnecessar=
y function/constructor call issue:</div>

<div><br></div><div>o.get_value_or(make_value()); // don't want to call mak=
e_value() when o is engaged</div><br></div></blockquote><div>&nbsp;<br>For =
this, how about an overload (or template specialization, or whatever) that =
accepts a functor that returns an appropriate type?<br><br>o.get_value_or([=
]{ return make_value();});<br><br>Robert<br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_480_6236755.1356827104120--

.


Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Sat, 29 Dec 2012 23:17:58 -0300
Raw View
On Sat, Dec 29, 2012 at 9:00 PM, Olaf van der Spek <olafvdspek@gmail.com> wrote:
> On Sat, Dec 29, 2012 at 8:33 PM, Fernando Cacciola
> <fernando.cacciola@gmail.com> wrote:
>>> I don't follow, how's that a problem?
>>> Returning the reference seems fine, storing it is the problem.
>>>
>>
>> Imagine get_value_or where to return a const&
>>
>> optional<string> o ;
>>
>> string const& v = o.get_value_or( "default" ) ;
>>
>> std::cout << v ; // This is UB. The temporary string was destroyed already
>
> Like I said, it's not the return type that's the problem but the type
> of v. Why did you pick a reference?
>
OK, I see your point and I think you are right.
If I want to access v then it makes no sense that I define it as a reference.
Furthermore:

auto v = o.get_value_or("default");

just works because auto is never a reference.

>
> On Sat, Dec 29, 2012 at 11:13 PM, Fernando Cacciola
> <fernando.cacciola@gmail.com> wrote:
>> What is not OK is the following:
>>
>> char const* fun( char const* p ) { return p ; }
>>
>> char const* p = fun(get().c_str());
>>
>> // AT THIS POINT p is dangling
>
> Not necessarily, if get() returns a reference to a string that's still alive.
>
>> And in fact, I'm pretty sure even this:
>>
>> bar( fun(get().c_str()) ) ;
>>
>> won't work, since AFAICT the full-expression that keeps the temporary
>> alive ends after the call to foo() completes, and it does not extend
>> to the call to bar.
>
> Don't think you're right here. IIRC temporaries stay alive until the
> sequence point (;).
>

You are are right. And I double check with VS2012.

So, your point is that we could have a consistent interface

T const& get_value_or( T const& ) ;

because the likelyhood of this resulting in a dangling reference is
not particularly greater than everything else in C++.
Right?

I agree in which case I would switch back to the original definition
(which is how it is in Boost.Optional BTW)

Andrzej, what do you think?

Best

--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com

--




.


Author: Fernando Cacciola <fernando.cacciola@gmail.com>
Date: Sat, 29 Dec 2012 23:50:40 -0300
Raw View
On Sat, Dec 29, 2012 at 7:28 PM, Vladimir Batov <vb.mail.247@gmail.com> wrote:
> It's does not sound like an optional problem. You'll get
> the same with any function:
>
> int const& v = some_func() ? some_func() : -1;
>
> And I suspect there is a simple solution to that. If one wants to
> re-use something (a result of a function), that needs to be stored
> (and re-used as many times as needed) with:
>
> int const& r = some_func();
> int const& v = r ? r : -1;
>

That's a valid alternative of course.

But then, not using optional is a valid alternative as well, so there
is only a certain extent into which we could cut out a feature on the
grounds that is not really needed. IMO this function is very
convenient because it allows you to use rvalue optionals.
I'm much happy with it if I can write

foo ( fetch().get_value_or(-1) ) ;

instead of:

auto const& v = fetch() ;
foo ( v ? *v : -1  ) ;

> It seems (IMO of course) that trying to avoid having 'r' comes at a
> too high a price.

If we positively resolve the issue of the return type, so the function
returns a const&, would you still consider the price too high?

AFAICT the only pending issue is the potentially unnecessary
construction of the default.

> I suspect it'll cause
> way more confusion than good. Again, IMO.
>
If we stick to the simple version returning const&, just as it is in
Boost.Optional, there would not be any confusion at all.


--
Fernando Cacciola
SciSoft Consulting, Founder
http://www.scisoft-consulting.com

--




.


Author: Vladimir Batov <vb.mail.247@gmail.com>
Date: Sun, 30 Dec 2012 15:22:23 +1100
Raw View
> On Sun, Dec 30, 2012 at 1:50 PM, Fernando Cacciola <fernando.cacciola@gmail.com> wrote:
>> On Sat, Dec 29, 2012 at 7:28 PM, Vladimir Batov <vb.mail.247@gmail.com> wrote:
>> It's does not sound like an optional problem. You'll get
>> the same with any function:
>>
>> int const& v = some_func() ? some_func() : -1;
>>
>> And I suspect there is a simple solution to that. If one wants to
>> re-use something (a result of a function), that needs to be stored
>> (and re-used as many times as needed) with:
>>
>> int const& r = some_func();
>> int const& v = r ? r : -1;
>
> That's a valid alternative of course.
>
> But then, not using optional is a valid alternative as well, so there
> is only a certain extent into which we could cut out a feature on the
> grounds that is not really needed.

I certainly see your point. Although I do feel that the suggestion of
not using optional at all is somewhat extreme. Although the above can
written as:

std::pair<bool, int> r = some_func();
int const& v = r.first ? r.second : -1;

it totally lacks the conceptual integrity (and often type safety) that
optional brings to the table.

> IMO this function is very
> convenient because it allows you to use rvalue optionals.
> I'm much happy with it if I can write
>
> foo ( fetch().get_value_or(-1) ) ;
>
> instead of:
>
> auto const& v = fetch() ;
> foo ( v ? *v : -1  ) ;

I totally understand! And in a short snippet like the above the
get_value_or-based version seems more appealing. In a more complex
code (where the result of fetch() might be needed in more places) that
advantage quickly evaporates (where, following your example above,
'optional' would still be immensely usable and useful). You might say,
if so, then fall-back to the standard way. And that's my concern
(well, 'concern' is somewhat too strong a word). I *personally* still
do not feel that get_value_or is sufficiently generic or uniformly,
widely enough useful to be part of as generic as the standard library.
Please do not take it as a criticism of any kind. It's merely my
observation, my point of view. I myself have quite a few gadgets (that
I consider essential for me) which make my work comfortable. However,
the stakes are much higher and requirements are much more stringent
when such gadgets are offered to wider public. The criteria of
universal usefulness, clear new functionality, etc., etc. need to be
applied. I feel that somewhat minimalistic approach's been quite
apparent in C++ evolution. Like that 'super' keyword (for the base
class) was not adopted because it could be done with 'typedef
base_class super;'.

My impression is that your "problem" (solved with get_value_or) is not
specific to optional. You are trying to call a function once but
re-use its result more than once. For various reasons you are not
satisfied with the conventional way of achieving that. However, I do
not feel that's correct to "solve" (with or without quotes) that quite
generic problem for optional only. So, if you are to go ahead with
get_value_or (most likely), then I feel that architecturally it is
more appropriate on the std level (as was your intention).

>> It seems (IMO of course) that trying to avoid having 'r' comes at a
>> too high a price.
>
> If we positively resolve the issue of the return type, so the function
> returns a const&, would you still consider the price too high?
>
> AFAICT the only pending issue is the potentially unnecessary
> construction of the default.
>
>> I suspect it'll cause
>> way more confusion than good. Again, IMO.
>>
> If we stick to the simple version returning const&, just as it is in
> Boost.Optional, there would not be any confusion at all.

You clearly know more about it than me. However, I can't help feeling
that get_value_or adds more complexity. That's just a little more.
Still, one needs to be aware of that little more in order *not* to be
confused. If/when every class adds just a little more, it becomes a
lot and very confusing. So, little by little the bar is pushed higher
and higher... and many consider C++ to be already too complex, arcane,
etc.

Another point is, I suspect, that even for the simple version
returning const& get_value_or is not out of the woods yet.

transformation const& v = fetch() ;
foo ( v ? *v : transformation::identity);

The above only calls
transformation::transformation(transformation::identity) if it's
needed.

foo(fetch().get_value_or(transformation::identity));

The above, indeed, can eliminate that constructor overhead with
get_value_or considerable implementation trickery... just to achieve
the same effect. That probably reflects quite well the way I feel
about get_value_or -- it requires a lot of thought and effort to get
it right and as efficient... just to get to where ?: takes us. Again,
please do not take my view (and that's all that is) the wrong way.

Best,
V.

--




.


Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Sun, 30 Dec 2012 14:38:58 +0100
Raw View
On Sun, Dec 30, 2012 at 5:22 AM, Vladimir Batov <vb.mail.247@gmail.com> wrote:
> I totally understand! And in a short snippet like the above the
> get_value_or-based version seems more appealing. In a more complex
> code (where the result of fetch() might be needed in more places) that
> advantage quickly evaporates (where, following your example above,

auto v = fetch().get_value_or(-1); // or
int v = fetch().get_value_or(-1);

You generally don't want to repeat the default value.


On Sun, Dec 30, 2012 at 3:17 AM, Fernando Cacciola
<fernando.cacciola@gmail.com> wrote:
>> Like I said, it's not the return type that's the problem but the type
>> of v. Why did you pick a reference?
>>
> OK, I see your point and I think you are right.
> If I want to access v then it makes no sense that I define it as a reference.
> Furthermore:
>
> auto v = o.get_value_or("default");
>
> just works because auto is never a reference.


> You are are right. And I double check with VS2012.
>
> So, your point is that we could have a consistent interface
>
> T const& get_value_or( T const& ) ;
>
> because the likelyhood of this resulting in a dangling reference is
> not particularly greater than everything else in C++.
> Right?

Yes, that's right.
You'd still want the && variant too to avoid a copy in

string s = f().get_value_or("");

And maybe you'd want a non-const& variant too.

Olaf

--




.


Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Mon, 31 Dec 2012 01:40:34 -0800 (PST)
Raw View
------=_Part_1532_154833.1356946835058
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable



W dniu niedziela, 30 grudnia 2012 01:25:04 UTC+1 u=BFytkownik R=F3bert D=E1=
vid=20
napisa=B3:
>
> Even if you fix that problem, how do you fix the performance / unnecessar=
y=20
>> function/constructor call issue:
>>
>> o.get_value_or(make_value()); // don't want to call make_value() when o=
=20
>> is engaged
>>
>> =20
> For this, how about an overload (or template specialization, or whatever)=
=20
> that accepts a functor that returns an appropriate type?
>
> o.get_value_or([]{ return make_value();});
>
> Robert
>

If lambda additions currently proposed get into the standard, the notation=
=20
would be even shorter:

o.get_value_or( [&] make_value() );

However, I am not sure if it is possible to always pick the correct=20
overload if there are two. What if the type of optional object o is=20
std::optional<std::function<void()>> ?
=20
Regards,
&rzej

--=20




------=_Part_1532_154833.1356946835058
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

<br><br>W dniu niedziela, 30 grudnia 2012 01:25:04 UTC+1 u=BFytkownik R=F3b=
ert D=E1vid napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div class=3D"gmail_quote"><div>Even if you=
 fix that problem, how do you fix the performance / unnecessary function/co=
nstructor call issue:</div>

<div><br></div><div>o.get_value_or(make_value()); // don't want to call mak=
e_value() when o is engaged</div><br></div></blockquote><div>&nbsp;<br>For =
this, how about an overload (or template specialization, or whatever) that =
accepts a functor that returns an appropriate type?<br><br>o.get_value_or([=
]{ return make_value();});<br><br>Robert<br></div></blockquote><div><br>If =
lambda additions currently proposed get into the standard, the notation wou=
ld be even shorter:<br><br><div class=3D"prettyprint" style=3D"background-c=
olor: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: s=
olid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint=
"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"style=
d-by-prettify">o</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">get=
_value_or</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">[&amp;]</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> make_value</span><spa=
n 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></div></code></div><br>However, I =
am not sure if it is possible to always pick the correct overload if there =
are two. What if the type of optional object <span style=3D"font-family: co=
urier new,monospace;">o</span> is <span style=3D"font-family: courier new,m=
onospace;">std::optional&lt;std::function&lt;void()&gt;&gt;</span> ?<br>&nb=
sp;<br>Regards,<br>&amp;rzej<br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_1532_154833.1356946835058--

.


Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Mon, 31 Dec 2012 01:46:58 -0800 (PST)
Raw View
------=_Part_1207_7544347.1356947218393
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable



W dniu niedziela, 30 grudnia 2012 03:17:58 UTC+1 u=BFytkownik Fernando=20
Cacciola napisa=B3:
>
> On Sat, Dec 29, 2012 at 9:00 PM, Olaf van der Spek <olafv...@gmail.com<ja=
vascript:>>=20
> wrote:=20
> > On Sat, Dec 29, 2012 at 8:33 PM, Fernando Cacciola=20
> > <fernando...@gmail.com <javascript:>> wrote:=20
> >>> I don't follow, how's that a problem?=20
> >>> Returning the reference seems fine, storing it is the problem.=20
> >>>=20
> >>=20
> >> Imagine get_value_or where to return a const&=20
> >>=20
> >> optional<string> o ;=20
> >>=20
> >> string const& v =3D o.get_value_or( "default" ) ;=20
> >>=20
> >> std::cout << v ; // This is UB. The temporary string was destroyed=20
> already=20
> >=20
> > Like I said, it's not the return type that's the problem but the type=
=20
> > of v. Why did you pick a reference?=20
> >=20
> OK, I see your point and I think you are right.=20
> If I want to access v then it makes no sense that I define it as a=20
> reference.=20
> Furthermore:=20
>
> auto v =3D o.get_value_or("default");=20
>
> just works because auto is never a reference.=20
>
> >=20
> > On Sat, Dec 29, 2012 at 11:13 PM, Fernando Cacciola=20
> > <fernando...@gmail.com <javascript:>> wrote:=20
> >> What is not OK is the following:=20
> >>=20
> >> char const* fun( char const* p ) { return p ; }=20
> >>=20
> >> char const* p =3D fun(get().c_str());=20
> >>=20
> >> // AT THIS POINT p is dangling=20
> >=20
> > Not necessarily, if get() returns a reference to a string that's still=
=20
> alive.=20
> >=20
> >> And in fact, I'm pretty sure even this:=20
> >>=20
> >> bar( fun(get().c_str()) ) ;=20
> >>=20
> >> won't work, since AFAICT the full-expression that keeps the temporary=
=20
> >> alive ends after the call to foo() completes, and it does not extend=
=20
> >> to the call to bar.=20
> >=20
> > Don't think you're right here. IIRC temporaries stay alive until the=20
> > sequence point (;).=20
> >=20
>
> You are are right. And I double check with VS2012.=20
>
> So, your point is that we could have a consistent interface=20
>
> T const& get_value_or( T const& ) ;=20
>
> because the likelyhood of this resulting in a dangling reference is=20
> not particularly greater than everything else in C++.=20
> Right?=20
>
> I agree in which case I would switch back to the original definition=20
> (which is how it is in Boost.Optional BTW)=20
>
> Andrzej, what do you think?=20
>

I am replying in a hurry, so pardon me if I talk nonsense, but I believe=20
that in order to optimize one case we pessimize the other. Consider this=20
example:

optional<vector<double>> getMatrix();
auto ans =3D getMatrix().get_value_or( optional<vector<double>>{} );=20

Given that vector's default and move constructors are cheap, and the copy=
=20
may be very expensive, by having get_value_or return a const& we prevent=20
move-based optimizations and copy elision.

Regards,
&rzej

--=20




------=_Part_1207_7544347.1356947218393
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

<br><br>W dniu niedziela, 30 grudnia 2012 03:17:58 UTC+1 u=BFytkownik Ferna=
ndo Cacciola napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Sat,=
 Dec 29, 2012 at 9:00 PM, Olaf van der Spek &lt;<a href=3D"javascript:" tar=
get=3D"_blank" gdf-obfuscated-mailto=3D"Vp8C_Q59sVwJ">olafv...@gmail.com</a=
>&gt; wrote:
<br>&gt; On Sat, Dec 29, 2012 at 8:33 PM, Fernando Cacciola
<br>&gt; &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailt=
o=3D"Vp8C_Q59sVwJ">fernando...@gmail.com</a>&gt; wrote:
<br>&gt;&gt;&gt; I don't follow, how's that a problem?
<br>&gt;&gt;&gt; Returning the reference seems fine, storing it is the prob=
lem.
<br>&gt;&gt;&gt;
<br>&gt;&gt;
<br>&gt;&gt; Imagine get_value_or where to return a const&amp;
<br>&gt;&gt;
<br>&gt;&gt; optional&lt;string&gt; o ;
<br>&gt;&gt;
<br>&gt;&gt; string const&amp; v =3D o.get_value_or( "default" ) ;
<br>&gt;&gt;
<br>&gt;&gt; std::cout &lt;&lt; v ; // This is UB. The temporary string was=
 destroyed already
<br>&gt;
<br>&gt; Like I said, it's not the return type that's the problem but the t=
ype
<br>&gt; of v. Why did you pick a reference?
<br>&gt;
<br>OK, I see your point and I think you are right.
<br>If I want to access v then it makes no sense that I define it as a refe=
rence.
<br>Furthermore:
<br>
<br>auto v =3D o.get_value_or("default");
<br>
<br>just works because auto is never a reference.
<br>
<br>&gt;
<br>&gt; On Sat, Dec 29, 2012 at 11:13 PM, Fernando Cacciola
<br>&gt; &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailt=
o=3D"Vp8C_Q59sVwJ">fernando...@gmail.com</a>&gt; wrote:
<br>&gt;&gt; What is not OK is the following:
<br>&gt;&gt;
<br>&gt;&gt; char const* fun( char const* p ) { return p ; }
<br>&gt;&gt;
<br>&gt;&gt; char const* p =3D fun(get().c_str());
<br>&gt;&gt;
<br>&gt;&gt; // AT THIS POINT p is dangling
<br>&gt;
<br>&gt; Not necessarily, if get() returns a reference to a string that's s=
till alive.
<br>&gt;
<br>&gt;&gt; And in fact, I'm pretty sure even this:
<br>&gt;&gt;
<br>&gt;&gt; bar( fun(get().c_str()) ) ;
<br>&gt;&gt;
<br>&gt;&gt; won't work, since AFAICT the full-expression that keeps the te=
mporary
<br>&gt;&gt; alive ends after the call to foo() completes, and it does not =
extend
<br>&gt;&gt; to the call to bar.
<br>&gt;
<br>&gt; Don't think you're right here. IIRC temporaries stay alive until t=
he
<br>&gt; sequence point (;).
<br>&gt;
<br>
<br>You are are right. And I double check with VS2012.
<br>
<br>So, your point is that we could have a consistent interface
<br>
<br>T const&amp; get_value_or( T const&amp; ) ;
<br>
<br>because the likelyhood of this resulting in a dangling reference is
<br>not particularly greater than everything else in C++.
<br>Right?
<br>
<br>I agree in which case I would switch back to the original definition
<br>(which is how it is in Boost.Optional BTW)
<br>
<br>Andrzej, what do you think?
<br></blockquote><div><br>I am replying in a hurry, so pardon me if I talk =
nonsense, but I believe that in order to optimize one case we pessimize the=
 other. Consider this example:<br><br><div class=3D"prettyprint" style=3D"b=
ackground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bord=
er-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"=
prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">optional</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">vector</span><span style=3D"color: #080;" class=3D"styled=
-by-prettify">&lt;double&gt;</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> getMatrix</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">a=
uto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> ans </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> getMatrix</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">().</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">get_value_or</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> optional</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">vector</span><span style=3D"color: #080;=
" class=3D"styled-by-prettify">&lt;double&gt;</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">&gt;{}</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"styl=
ed-by-prettify"> <br></span></div></code></div><br>Given that <span style=
=3D"font-family: courier new,monospace;">vector</span>'s default and move c=
onstructors are cheap, and the copy may be very expensive, by having <code =
class=3D"prettyprint"><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">get_value_or</span><span style=3D"font-family: arial,sans-serif;"><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify"> re</span></span></co=
de>turn a <span style=3D"font-family: courier new,monospace;">const&amp;</s=
pan> we prevent move-based optimizations and copy elision.<br><br>Regards,<=
br>&amp;rzej<br><br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_1207_7544347.1356947218393--

.


Author: =?UTF-8?Q?R=C3=B3bert_D=C3=A1vid?= <lrdxgm@gmail.com>
Date: Mon, 31 Dec 2012 08:31:01 -0800 (PST)
Raw View
------=_Part_9_25308811.1356971461810
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

2012. december 31., h=E9tf=F5 10:40:34 UTC+1 id=F5pontban Andrzej Krzemie=
=F1ski a=20
k=F6vetkez=F5t =EDrta:
>
>
>
> W dniu niedziela, 30 grudnia 2012 01:25:04 UTC+1 u=BFytkownik R=F3bert D=
=E1vid=20
> napisa=B3:
>>
>> Even if you fix that problem, how do you fix the performance /=20
>>> unnecessary function/constructor call issue:
>>>
>>> o.get_value_or(make_value()); // don't want to call make_value() when o=
=20
>>> is engaged
>>>
>>> =20
>> For this, how about an overload (or template specialization, or whatever=
)=20
>> that accepts a functor that returns an appropriate type?
>>
>> o.get_value_or([]{ return make_value();});
>>
>> Robert
>>
>
> If lambda additions currently proposed get into the standard, the notatio=
n=20
> would be even shorter:
>
> o.get_value_or( [&] make_value() );
>
> However, I am not sure if it is possible to always pick the correct=20
> overload if there are two. What if the type of optional object o is=20
> std::optional<std::function<void()>> ?
> =20
> Regards,
> &rzej
>

I think a similar issue made find and find_if to be not an overload, but a=
=20
different function. Using that idea for std::optional:
o.get_value_or_call([&]make_value());

There should be a better name, three underscores are getting a bit too much=
=20
for my taste though :) I just could not find anything better yet.

Regards,
Robert

--=20




------=_Part_9_25308811.1356971461810
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

2012. december 31., h=E9tf=F5 10:40:34 UTC+1 id=F5pontban Andrzej Krzemie=
=F1ski a k=F6vetkez=F5t =EDrta:<blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
><br><br>W dniu niedziela, 30 grudnia 2012 01:25:04 UTC+1 u=BFytkownik R=F3=
bert D=E1vid napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin:0;=
margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote =
class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #=
ccc solid;padding-left:1ex"><div class=3D"gmail_quote"><div>Even if you fix=
 that problem, how do you fix the performance / unnecessary function/constr=
uctor call issue:</div>

<div><br></div><div>o.get_value_or(make_value()); // don't want to call mak=
e_value() when o is engaged</div><br></div></blockquote><div>&nbsp;<br>For =
this, how about an overload (or template specialization, or whatever) that =
accepts a functor that returns an appropriate type?<br><br>o.get_value_or([=
]{ return make_value();});<br><br>Robert<br></div></blockquote><div><br>If =
lambda additions currently proposed get into the standard, the notation wou=
ld be even shorter:<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:#000">o</span><span style=3D"c=
olor:#660">.</span><span style=3D"color:#000">get_value_or</span><span styl=
e=3D"color:#660">(</span><span style=3D"color:#000"> </span><span style=3D"=
color:#660">[&amp;]</span><span style=3D"color:#000"> make_value</span><spa=
n style=3D"color:#660">()</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#660">);</span><span style=3D"color:#000"><br></span></div></c=
ode></div><br>However, I am not sure if it is possible to always pick the c=
orrect overload if there are two. What if the type of optional object <span=
 style=3D"font-family:courier new,monospace">o</span> is <span style=3D"fon=
t-family:courier new,monospace">std::optional&lt;std::function&lt;<wbr>void=
()&gt;&gt;</span> ?<br>&nbsp;<br>Regards,<br>&amp;rzej<br></div></blockquot=
e><div><br>I think a similar issue made <span style=3D"font-family: courier=
 new,monospace;">find</span> and <span style=3D"font-family: courier new,mo=
nospace;">find_if</span> to be not an overload, but a different function. U=
sing that idea for <span style=3D"font-family: courier new,monospace;">std:=
:optional</span>:<br><div class=3D"prettyprint" 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 class=3D"prettyprint"><div=
 class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">o</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
..</span><span style=3D"color: #000;" class=3D"styled-by-prettify">get_value=
_or</span><span style=3D"color: #000;" class=3D"styled-by-prettify">_call</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">([&amp;]</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">make_value</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">());</span></d=
iv></code></div><br>There should be a better name, three underscores are ge=
tting a bit too much for my taste though :) I just could not find anything =
better yet.<br><br>Regards,<br>Robert<br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_9_25308811.1356971461810--

.


Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Wed, 2 Jan 2013 01:14:27 -0800 (PST)
Raw View
------=_Part_898_22977129.1357118067302
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable



W dniu poniedzia=B3ek, 31 grudnia 2012 17:31:01 UTC+1 u=BFytkownik R=F3bert=
 D=E1vid=20
napisa=B3:
>
> 2012. december 31., h=E9tf=F5 10:40:34 UTC+1 id=F5pontban Andrzej Krzemie=
=F1ski a=20
> k=F6vetkez=F5t =EDrta:
>>
>>
>>
>> W dniu niedziela, 30 grudnia 2012 01:25:04 UTC+1 u=BFytkownik R=F3bert D=
=E1vid=20
>> napisa=B3:
>>>
>>> Even if you fix that problem, how do you fix the performance /=20
>>>> unnecessary function/constructor call issue:
>>>>
>>>> o.get_value_or(make_value()); // don't want to call make_value() when =
o=20
>>>> is engaged
>>>>
>>>> =20
>>> For this, how about an overload (or template specialization, or=20
>>> whatever) that accepts a functor that returns an appropriate type?
>>>
>>> o.get_value_or([]{ return make_value();});
>>>
>>> Robert
>>>
>>
>> If lambda additions currently proposed get into the standard, the=20
>> notation would be even shorter:
>>
>> o.get_value_or( [&] make_value() );
>>
>> However, I am not sure if it is possible to always pick the correct=20
>> overload if there are two. What if the type of optional object o is=20
>> std::optional<std::function<void()>> ?
>> =20
>> Regards,
>> &rzej
>>
>
> I think a similar issue made find and find_if to be not an overload, but=
=20
> a different function. Using that idea for std::optional:
> o.get_value_or_call([&]make_value());
>
> There should be a better name, three underscores are getting a bit too=20
> much for my taste though :) I just could not find anything better yet.
>

Another thing we could do here, is to provide only the variant that takes=
=20
the functor. If the user prefers giving only the default value, he will=20
have to express it using a lambda:

int fun( optional<int> o ) {
  return o.get_value_or( [&] -1 );
}

Looks a bit odd at first, but could become an idiom in C++14.

Regards,
&rzej



--=20




------=_Part_898_22977129.1357118067302
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

<br><br>W dniu poniedzia=B3ek, 31 grudnia 2012 17:31:01 UTC+1 u=BFytkownik =
R=F3bert D=E1vid napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">201=
2. december 31., h=E9tf=F5 10:40:34 UTC+1 id=F5pontban Andrzej Krzemie=F1sk=
i a k=F6vetkez=F5t =EDrta:<blockquote class=3D"gmail_quote" style=3D"margin=
:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><br><br>W=
 dniu niedziela, 30 grudnia 2012 01:25:04 UTC+1 u=BFytkownik R=F3bert D=E1v=
id napisa=B3:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class=3D"g=
mail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div class=3D"gmail_quote"><div>Even if you fix that prob=
lem, how do you fix the performance / unnecessary function/constructor call=
 issue:</div>

<div><br></div><div>o.get_value_or(make_value()); // don't want to call mak=
e_value() when o is engaged</div><br></div></blockquote><div>&nbsp;<br>For =
this, how about an overload (or template specialization, or whatever) that =
accepts a functor that returns an appropriate type?<br><br>o.get_value_or([=
]{ return make_value();});<br><br>Robert<br></div></blockquote><div><br>If =
lambda additions currently proposed get into the standard, the notation wou=
ld be even shorter:<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:#000">o</span><span style=3D"c=
olor:#660">.</span><span style=3D"color:#000">get_value_or</span><span styl=
e=3D"color:#660">(</span><span style=3D"color:#000"> </span><span style=3D"=
color:#660">[&amp;]</span><span style=3D"color:#000"> make_value</span><spa=
n style=3D"color:#660">()</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#660">);</span><span style=3D"color:#000"><br></span></div></c=
ode></div><br>However, I am not sure if it is possible to always pick the c=
orrect overload if there are two. What if the type of optional object <span=
 style=3D"font-family:courier new,monospace">o</span> is <span style=3D"fon=
t-family:courier new,monospace">std::optional&lt;std::function&lt;<wbr>void=
()&gt;&gt;</span> ?<br>&nbsp;<br>Regards,<br>&amp;rzej<br></div></blockquot=
e><div><br>I think a similar issue made <span style=3D"font-family:courier =
new,monospace">find</span> and <span style=3D"font-family:courier new,monos=
pace">find_if</span> to be not an overload, but a different function. Using=
 that idea for <span style=3D"font-family:courier new,monospace">std::optio=
nal</span>:<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:#000">o</span><span style=3D"color:#660">.=
</span><span style=3D"color:#000">get_value_or</span><span style=3D"color:#=
000">_call</span><span style=3D"color:#660">([&amp;]</span><span style=3D"c=
olor:#000">make_<wbr>value</span><span style=3D"color:#660">());</span></di=
v></code></div><br>There should be a better name, three underscores are get=
ting a bit too much for my taste though :) I just could not find anything b=
etter yet.<br></div></blockquote><div><br>Another thing we could do here, i=
s to provide only the variant that takes the functor. If the user prefers g=
iving only the default value, he will have to express it using a lambda:<br=
><br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 25=
0); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1p=
x; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpre=
ttyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">int</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> fun</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> optional</span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">&lt;int&gt;</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> o </span><span style=3D"co=
lor: #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>&nbsp; </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">return</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> o</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">get_v=
alue_or</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: #660;" class=3D"styled-by-prettify">[&amp;]</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">-</span><span style=3D"color: #06=
6;" class=3D"styled-by-prettify">1</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></sp=
an></div></code></div><br>Looks a bit odd at first, but could become an idi=
om in C++14.<br><br>Regards,<br>&amp;rzej<br><br><br><br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_898_22977129.1357118067302--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Wed, 2 Jan 2013 09:41:10 -0600
Raw View
--000e0cd3b600ea24fd04d250154b
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On 2 January 2013 03:14, Andrzej Krzemie=C5=84ski <akrzemi1@gmail.com> wrot=
e:

>
>
>
> int fun( optional<int> o ) {
>   return o.get_value_or( [&] -1 );
> }
>
> Looks a bit odd at first, but could become an idiom in C++14.
>

-1, as it isn't an obvious interface.  This is beginning to feel like we
are adding a function just for the sake of doing so.
--=20
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--=20




--000e0cd3b600ea24fd04d250154b
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On 2 January 2013 03:14, Andrzej Krzemie=C5=84ski <span dir=3D"ltr">&lt;<a =
href=3D"mailto:akrzemi1@gmail.com" target=3D"_blank">akrzemi1@gmail.com</a>=
&gt;</span> wrote:<br><div class=3D"gmail_quote"><blockquote class=3D"gmail=
_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:=
1ex">

<br><br><div><br><div style=3D"background-color:rgb(250,250,250);border-col=
or:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-wor=
d"><code><div><span style=3D"color:#008">int</span><span style> fun</span><=
span style=3D"color:#660">(</span><span style> optional</span><span style=
=3D"color:#080">&lt;int&gt;</span><span style> o </span><span style=3D"colo=
r:#660">)</span><span style> </span><span style=3D"color:#660">{</span><spa=
n style><br>

=C2=A0 </span><span style=3D"color:#008">return</span><span style> o</span>=
<span style=3D"color:#660">.</span><span style>get_value_or</span><span sty=
le=3D"color:#660">(</span><span style> </span><span style=3D"color:#660">[&=
amp;]</span><span style> </span><span style=3D"color:#660">-</span><span st=
yle=3D"color:#066">1</span><span style> </span><span style=3D"color:#660">)=
;</span><span style><br>

</span><span style=3D"color:#660">}</span><span style><br></span></div></co=
de></div><br>Looks a bit odd at first, but could become an idiom in C++14.<=
br></div></blockquote><div><br>-1, as it isn&#39;t an obvious interface.=C2=
=A0 This is beginning to feel like we are adding a function just for the sa=
ke of doing so.<br>

</div></div>-- <br>=C2=A0Nevin &quot;:-)&quot; Liber=C2=A0 &lt;mailto:<a hr=
ef=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.c=
om</a>&gt;=C2=A0 (847) 691-1404

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

--000e0cd3b600ea24fd04d250154b--

.


Author: =?UTF-8?Q?R=C3=B3bert_D=C3=A1vid?= <lrdxgm@gmail.com>
Date: Wed, 2 Jan 2013 11:38:18 -0800 (PST)
Raw View
------=_Part_655_31187585.1357155498511
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable


2013. janu=E1r 2., szerda 10:14:27 UTC+1 id=F5pontban Andrzej Krzemie=F1ski=
 a=20
k=F6vetkez=F5t =EDrta:
>
> Another thing we could do here, is to provide only the variant that takes=
=20
> the functor. If the user prefers giving only the default value, he will=
=20
> have to express it using a lambda:
>
> int fun( optional<int> o ) {
>   return o.get_value_or( [&] -1 );
> }
>
> Looks a bit odd at first, but could become an idiom in C++14.
>
=20
I would still keep the previous version that just takes a value, for=20
simplicity, otherwise no average programmer will look at the freshly=20
printed standard (or the fresh compiler's documentation), see this=20
interface of get_value_or, and think "yes, just what I need".

Regards,
Robert

--=20




------=_Part_655_31187585.1357155498511
Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

<br>2013. janu=E1r 2., szerda 10:14:27 UTC+1 id=F5pontban Andrzej Krzemie=
=F1ski a k=F6vetkez=F5t =EDrta:<blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
>Another thing we could do here, is to provide only the variant that takes =
the functor. If the user prefers giving only the default value, he will hav=
e to express it using a lambda:<br><div><br><div style=3D"background-color:=
rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wi=
dth:1px;word-wrap:break-word"><code><div><span style=3D"color:#008">int</sp=
an><span style=3D"color:#000"> fun</span><span style=3D"color:#660">(</span=
><span style=3D"color:#000"> optional</span><span style=3D"color:#080">&lt;=
int&gt;</span><span style=3D"color:#000"> o </span><span style=3D"color:#66=
0">)</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{<=
/span><span style=3D"color:#000"><br>&nbsp; </span><span style=3D"color:#00=
8">return</span><span style=3D"color:#000"> o</span><span style=3D"color:#6=
60">.</span><span style=3D"color:#000">get_value_or</span><span style=3D"co=
lor:#660">(</span><span style=3D"color:#000"> </span><span style=3D"color:#=
660">[&amp;]</span><span style=3D"color:#000"> </span><span style=3D"color:=
#660">-</span><span style=3D"color:#066">1</span><span style=3D"color:#000"=
> </span><span style=3D"color:#660">);</span><span style=3D"color:#000"><br=
></span><span style=3D"color:#660">}</span><span style=3D"color:#000"><br><=
/span></div></code></div><br>Looks a bit odd at first, but could become an =
idiom in C++14.<br></div></blockquote><div>&nbsp;<br>I would still keep the=
 previous version that just takes a value, for simplicity, otherwise no ave=
rage programmer will look at the freshly printed standard (or the fresh com=
piler's documentation), see this interface of get_value_or, and think "yes,=
 just what I need".<br><br>Regards,<br>Robert<br></div>

<p></p>

-- <br />
&nbsp;<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_655_31187585.1357155498511--

.