Topic: optional<bool>


Author: Tony V E <tvaneerd@gmail.com>
Date: Thu, 29 Aug 2013 18:49:03 -0400
Raw View
--001a11345984aef86504e51de99c
Content-Type: text/plain; charset=ISO-8859-1

optional<bool> has some issues which boost::optional<> avoided by saying
"use boost::tribool instead" (this was seen in the original Boost review
way back when).  But there is currently no std::tribool nor a proposal for
one.  So I expect optional<bool> will be used instead in many cases.

Main issue: operator bool does not return the same thing as comparison to
bool. ie

optional<bool> opt = false;

// A
if (!opt) {
  doSomething();
}

// B
if (opt == false)  {
   doSomething();
}


The above 2 if-blocks are not the same.  Same problem with checking against
'true' obviously.

Now, I don't really want to lose "if (opt)" doing an 'engaged' check *in
general* for optional<T>, but I'm wondering if:

- is it possible to make these cases ambiguous for optional<bool> only.  ie
instead of picking A or B it just doesn't compile.

- if it is possible, is that a palatable solution?  (Note that there are
alternatives for both cases - ie an explicit is_engaged() function (I
think, or whatever it is called) vs an explicit dereference - "*opt ==
false" or check + deref.

I suspect the only people that would do things explicitly would typically
be template authors, who don't know whether optional<T> is optional<bool>
or not.

Tony

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

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

<div dir=3D"ltr"><div><div><div><div>optional&lt;bool&gt; has some issues w=
hich boost::optional&lt;&gt; avoided by saying &quot;use boost::tribool ins=
tead&quot; (this was seen in the original Boost review way back when).=A0 B=
ut there is currently no std::tribool nor a proposal for one.=A0 So I expec=
t optional&lt;bool&gt; will be used instead in many cases.<br>
<br></div>Main issue: operator bool does not return the same thing as compa=
rison to bool. ie<br><br></div>optional&lt;bool&gt; opt =3D false;<br><br><=
/div><div>// A<br></div><div>if (!opt) {<br></div><div>=A0 doSomething();<b=
r>
</div><div>}<br><br></div><div>// B<br></div><div>if (opt =3D=3D false)=A0 =
{<br></div><div>=A0=A0 doSomething();<br></div><div>}<br><br><br></div><div=
>The above 2 if-blocks are not the same.=A0 Same problem with checking agai=
nst &#39;true&#39; obviously.<br>
</div><div><br></div><div>Now, I don&#39;t really want to lose &quot;if (op=
t)&quot; doing an &#39;engaged&#39; check *in general* for optional&lt;T&gt=
;, but I&#39;m wondering if:<br><br></div><div>- is it possible to make the=
se cases ambiguous for optional&lt;bool&gt; only.=A0 ie instead of picking =
A or B it just doesn&#39;t compile.<br>
<br></div><div>- if it is possible, is that a palatable solution?=A0 (Note =
that there are alternatives for both cases - ie an explicit is_engaged() fu=
nction (I think, or whatever it is called) vs an explicit dereference - &qu=
ot;*opt =3D=3D false&quot; or check + deref.<br>
<br></div><div>I suspect the only people that would do things explicitly wo=
uld typically be template authors, who don&#39;t know whether optional&lt;T=
&gt; is optional&lt;bool&gt; or not.<br></div><div><br></div><div>Tony<br>
</div><div><br></div><br></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--001a11345984aef86504e51de99c--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 29 Aug 2013 16:56:24 -0700 (PDT)
Raw View
------=_Part_119_25064588.1377820584816
Content-Type: text/plain; charset=ISO-8859-1



On Thursday, August 29, 2013 3:49:03 PM UTC-7, Tony V E wrote:
>
> optional<bool> has some issues which boost::optional<> avoided by saying
> "use boost::tribool instead" (this was seen in the original Boost review
> way back when).  But there is currently no std::tribool nor a proposal for
> one.  So I expect optional<bool> will be used instead in many cases.
>
> Main issue: operator bool does not return the same thing as comparison to
> bool. ie
>
> optional<bool> opt = false;
>
> // A
> if (!opt) {
>   doSomething();
> }
>
> // B
> if (opt == false)  {
>    doSomething();
> }
>
>
> The above 2 if-blocks are not the same.  Same problem with checking
> against 'true' obviously.
>
> Now, I don't really want to lose "if (opt)" doing an 'engaged' check *in
> general* for optional<T>, but I'm wondering if:
>
> - is it possible to make these cases ambiguous for optional<bool> only.
> ie instead of picking A or B it just doesn't compile.
>

Sure, it's possible. std::enable_if gimmicks can remove the `explicit
operator bool` function if T == bool.


> - if it is possible, is that a palatable solution?  (Note that there are
> alternatives for both cases - ie an explicit is_engaged() function (I
> think, or whatever it is called) vs an explicit dereference - "*opt ==
> false" or check + deref.
>

*Absolutely not.*

optional<bool> is a perfectly legitimate construct, so long as you
understand what it *means* and how to work with it. If you don't, then
you'll have problems. But it's not our job to fix that; it's your job to
know what you're doing.

Let's learn the lessons of `vector<bool>`: don't change the interface to
different instantiations of a template. Not unless it's because the type T
flat-out doesn't support that operation.

I'm not saying that I'd be against `tribool`. But we shouldn't damage or
inhibit `optional` just because we don't have a `tribool` around. It's up
to the individual programmers to decide which construct makes more sense to
them: optional<bool> or tribool.

I suspect the only people that would do things explicitly would typically
> be template authors, who don't know whether optional<T> is optional<bool>
> or not.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

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

<div dir=3D"ltr"><br><br>On Thursday, August 29, 2013 3:49:03 PM UTC-7, Ton=
y V E wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><=
div><div><div><div>optional&lt;bool&gt; has some issues which boost::option=
al&lt;&gt; avoided by saying "use boost::tribool instead" (this was seen in=
 the original Boost review way back when).&nbsp; But there is currently no =
std::tribool nor a proposal for one.&nbsp; So I expect optional&lt;bool&gt;=
 will be used instead in many cases.<br>
<br></div>Main issue: operator bool does not return the same thing as compa=
rison to bool. ie<br><br></div>optional&lt;bool&gt; opt =3D false;<br><br><=
/div><div>// A<br></div><div>if (!opt) {<br></div><div>&nbsp; doSomething()=
;<br>
</div><div>}<br><br></div><div>// B<br></div><div>if (opt =3D=3D false)&nbs=
p; {<br></div><div>&nbsp;&nbsp; doSomething();<br></div><div>}<br><br><br><=
/div><div>The above 2 if-blocks are not the same.&nbsp; Same problem with c=
hecking against 'true' obviously.<br>
</div><div><br></div><div>Now, I don't really want to lose "if (opt)" doing=
 an 'engaged' check *in general* for optional&lt;T&gt;, but I'm wondering i=
f:<br><br></div><div>- is it possible to make these cases ambiguous for opt=
ional&lt;bool&gt; only.&nbsp; ie instead of picking A or B it just doesn't =
compile.<br></div></div></div></blockquote><div><br>Sure, it's possible. st=
d::enable_if gimmicks can remove the `explicit operator bool` function if T=
 =3D=3D bool.<br>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><=
div dir=3D"ltr"><div><div>
</div><div>- if it is possible, is that a palatable solution?&nbsp; (Note t=
hat there are alternatives for both cases - ie an explicit is_engaged() fun=
ction (I think, or whatever it is called) vs an explicit dereference - "*op=
t =3D=3D false" or check + deref.<br></div></div></div></blockquote><div><b=
r><i>Absolutely not.</i><br><br>optional&lt;bool&gt; is a perfectly legitim=
ate construct, so long as you understand what it <i>means</i> and how to wo=
rk with it. If you don't, then you'll have problems. But it's not our job t=
o fix that; it's your job to know what you're doing.<br><br>Let's learn the=
 lessons of `vector&lt;bool&gt;`: don't change the interface to different i=
nstantiations of a template. Not unless it's because the type T flat-out do=
esn't support that operation.<br><br>I'm not saying that I'd be against `tr=
ibool`. But we shouldn't damage or inhibit `optional` just because we don't=
 have a `tribool` around. It's up to the individual programmers to decide w=
hich construct makes more sense to them: optional&lt;bool&gt; or tribool.<b=
r><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><=
div><div>I suspect the only people that would do things explicitly would ty=
pically be template authors, who don't know whether optional&lt;T&gt; is op=
tional&lt;bool&gt; or not.</div></div></div>
</blockquote></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_119_25064588.1377820584816--

.


Author: Bjorn Reese <breese@mail1.stofanet.dk>
Date: Fri, 30 Aug 2013 12:20:36 +0200
Raw View
On 08/30/2013 12:49 AM, Tony V E wrote:

> way back when).  But there is currently no std::tribool nor a proposal
> for one.  So I expect optional<bool> will be used instead in many cases.

There is N2136, but I do not know its current status.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Fri, 30 Aug 2013 17:09:52 -0400
Raw View
--089e0160b572c5272a04e530a41c
Content-Type: text/plain; charset=ISO-8859-1

> - is it possible to make these cases ambiguous for optional<bool> only.
> ie instead of picking A or B it just doesn't compile.
>

> Sure, it's possible. std::enable_if gimmicks can remove the `explicit
> operator bool` function if T == bool.
>

removing the explicit operator would make A not compile, but B still
compiles.  I'd prefer the other way around, or neither.
removing just the 'explicit' part would probably make A compile, and make B
ambiguous, but I suspect it would have other unpleasant ramifications.


>
>
>> - if it is possible, is that a palatable solution?  (Note that there are
>> alternatives for both cases - ie an explicit is_engaged() function (I
>> think, or whatever it is called) vs an explicit dereference - "*opt ==
>> false" or check + deref.
>>
>
> *Absolutely not.*
>
> optional<bool> is a perfectly legitimate construct, so long as you
> understand what it *means* and how to work with it. If you don't, then
> you'll have problems. But it's not our job to fix that; it's your job to
> know what you're doing.
>
>
I think it is our job to make APIs that are clear and usable. C++ already
has enough gotchas.  If coding guidelines end up saying "always explicitly
use opt != nullopt instead of just i (opt)", then we have failed.



> Let's learn the lessons of `vector<bool>`: don't change the interface to
> different instantiations of a template. Not unless it's because the type T
> flat-out doesn't support that operation.
>
>
vector<bool> is a good point.  I don't think not-compiling is quite as
extreme as vector<bool>, but I still agree your point has merit.

The alternative is to not do conversion to bool at all (for any T), ie
force it to always be explicit opt == nullopt and opt != nullopt.  I think
there is similarity here to if (ptr) vs if (ptr == nullptr) and other
issues with 0 converting to/from pointers, and the need for nullptr.  Is
optional<> making a similar mistake?

I'm not totally against if (opt) and actually use if (ptr) instead of if
(ptr == nullptr), but I think it is important to understand the "cost" of
optional's conversion operator.  I don't think the subtlety of
optional<bool> was considered when optional was being voted on.  Maybe
everyone is OK with it, but I just want to know they are *aware* of it.

Tony

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

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

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><blockquote class=3D"gmail_=
quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddi=
ng-left:1ex"><div dir=3D"ltr"><div><div>- is it possible to make these case=
s ambiguous for optional&lt;bool&gt; only.=A0 ie instead of picking A or B =
it just doesn&#39;t compile.<br>
</div></div></div></blockquote><div class=3D"gmail_quote"><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div><br>Sure, it&#39;s possible. std::enabl=
e_if gimmicks can remove the `explicit operator bool` function if T =3D=3D =
bool.<br>
</div></div></blockquote><div><br></div><div>removing the explicit operator=
 would make A not compile, but B still compiles.=A0 I&#39;d prefer the othe=
r way around, or neither.<br></div><div>removing just the &#39;explicit&#39=
; part would probably make A compile, and make B ambiguous, but I suspect i=
t would have other unpleasant ramifications.<br>
</div><div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0=
 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>=
=A0</div><div class=3D"im"><blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir=3D"ltr"><div><div>
</div><div>- if it is possible, is that a palatable solution?=A0 (Note that=
 there are alternatives for both cases - ie an explicit is_engaged() functi=
on (I think, or whatever it is called) vs an explicit dereference - &quot;*=
opt =3D=3D false&quot; or check + deref.<br>
</div></div></div></blockquote></div><div><br><i>Absolutely not.</i><br><br=
>optional&lt;bool&gt; is a perfectly legitimate construct, so long as you u=
nderstand what it <i>means</i> and how to work with it. If you don&#39;t, t=
hen you&#39;ll have problems. But it&#39;s not our job to fix that; it&#39;=
s your job to know what you&#39;re doing.<br>
<br></div></div></blockquote><div><br></div><div>I think it is our job to m=
ake APIs that are clear and usable. C++ already has enough gotchas.=A0 If c=
oding guidelines end up saying &quot;always explicitly use opt !=3D nullopt=
 instead of just i (opt)&quot;, then we have failed.<br>
</div><div><br>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0=
 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><di=
v>Let&#39;s learn the lessons of `vector&lt;bool&gt;`: don&#39;t change the=
 interface to different instantiations of a template. Not unless it&#39;s b=
ecause the type T flat-out doesn&#39;t support that operation.<br>
<br></div></div></blockquote><div><br></div><div>vector&lt;bool&gt; is a go=
od point.=A0 I don&#39;t think not-compiling is quite as extreme as vector&=
lt;bool&gt;, but I still agree your point has merit.<br><br></div>The alter=
native is to not do conversion to bool at all (for any T), ie force it to a=
lways be explicit opt =3D=3D nullopt and opt !=3D nullopt.=A0 I think there=
 is similarity here to if (ptr) vs if (ptr =3D=3D nullptr) and other issues=
 with 0 converting to/from pointers, and the need for nullptr.=A0 Is option=
al&lt;&gt; making a similar mistake?<br>
<br></div><div class=3D"gmail_quote">I&#39;m not totally against if (opt) a=
nd actually use if (ptr) instead of if (ptr =3D=3D nullptr), but I think it=
 is important to understand the &quot;cost&quot; of optional&#39;s conversi=
on operator.=A0 I don&#39;t think the subtlety of optional&lt;bool&gt; was =
considered when optional was being voted on.=A0 Maybe everyone is OK with i=
t, but I just want to know they are *aware* of it.<br>
<br>Tony<br></div><br></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e0160b572c5272a04e530a41c--

.


Author: Jeffrey Yasskin <jyasskin@google.com>
Date: Fri, 30 Aug 2013 14:13:25 -0700
Raw View
On Fri, Aug 30, 2013 at 2:09 PM, Tony V E <tvaneerd@gmail.com> wrote:
> The alternative is to not do conversion to bool at all (for any T), ie force
> it to always be explicit opt == nullopt and opt != nullopt.  I think there
> is similarity here to if (ptr) vs if (ptr == nullptr) and other issues with
> 0 converting to/from pointers, and the need for nullptr.  Is optional<>
> making a similar mistake?
>
> I'm not totally against if (opt) and actually use if (ptr) instead of if
> (ptr == nullptr), but I think it is important to understand the "cost" of
> optional's conversion operator.  I don't think the subtlety of
> optional<bool> was considered when optional was being voted on.  Maybe
> everyone is OK with it, but I just want to know they are *aware* of it.

It was mentioned in the paper
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3527.html#rationale.bool_conversion),
just not discussed to death like some other issues. I think people
were adequately aware of it.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Fri, 30 Aug 2013 18:05:38 -0400
Raw View
--089e0149401035887604e5316c13
Content-Type: text/plain; charset=ISO-8859-1

On Fri, Aug 30, 2013 at 5:13 PM, Jeffrey Yasskin <jyasskin@google.com>wrote:

> > Maybe everyone is OK with it, but I just want to know they are *aware*
> of it.
>
> It was mentioned in the paper
> (
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3527.html#rationale.bool_conversion
> ),
> just not discussed to death like some other issues.


:-)



> I think people
> were adequately aware of it.
>
>
I don't think the paper highlights the problem clearly.  ie the paper says

" types bool*, unique_ptr<bool>, shared_ptr<bool> suffer from the same
potential problem,  "

yet they do not, because they do not have the mixed relational operators.

So for the above types,

    if (boolptr)

and

    if (boolptr == false)

*ARE* the same.

Yes, for the above types, there is some confusion as to

   if (boolptr)

did the programmer mean...

    if (*boolptr)

....?  But there isn't the flat-out "contradiction" of

     optional<bool> boolopt = false;

     assert( !boolopt != (boolopt == false) );

that only optional<bool> has.

(I think. Or did I miss mixed-relational-operators in smart pointers or
something?)

Tony

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

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

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
_quote">On Fri, Aug 30, 2013 at 5:13 PM, Jeffrey Yasskin <span dir=3D"ltr">=
&lt;<a href=3D"mailto:jyasskin@google.com" target=3D"_blank">jyasskin@googl=
e.com</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><div class=3D"im">&gt; Ma=
ybe everyone is OK with it, but I just want to know they are *aware* of it.=
<br>

<br>
</div>It was mentioned in the paper<br>
(<a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3527.h=
tml#rationale.bool_conversion" target=3D"_blank">http://www.open-std.org/jt=
c1/sc22/wg21/docs/papers/2013/n3527.html#rationale.bool_conversion</a>),<br=
>

just not discussed to death like some other issues.</blockquote><div><br>:-=
)<br><br>=A0<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px=
 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> I =
think people<br>

were adequately aware of it.<br>
<div class=3D""><div class=3D"h5"><br></div></div></blockquote><div><br></d=
iv><div>I don&#39;t think the paper highlights the problem clearly.=A0 ie t=
he paper says<br><br>&quot; types <code>bool*</code>, <code>unique_ptr&lt;b=
ool&gt;</code>, <code>shared_ptr&lt;bool&gt;</code> suffer from the same po=
tential problem,=A0 &quot;<br>
<br></div><div>yet they do not, because they do not have the mixed relation=
al operators.<br><br></div><div>So for the above types,<br></div><br><div>=
=A0=A0=A0 if (boolptr)<br><br></div><div>and<br><br>=A0=A0=A0 if (boolptr =
=3D=3D false)<br>
<br></div><div>*ARE* the same.<br><br></div><div>Yes, for the above types, =
there is some confusion as to<br><br></div><div>=A0=A0 if (boolptr)<br><br>=
did the programmer mean...<br><br>=A0=A0=A0 if (*boolptr)<br><br></div><div=
>...?=A0 But there isn&#39;t the flat-out &quot;contradiction&quot; of <br>
<br></div><div>=A0=A0=A0=A0 optional&lt;bool&gt; boolopt =3D false;<br><br>=
</div><div>=A0=A0=A0=A0 assert( !boolopt !=3D (boolopt =3D=3D false) );<br>=
<br></div><div>that only optional&lt;bool&gt; has.<br><br></div><div>(I thi=
nk. Or did I miss mixed-relational-operators in smart pointers or something=
?)<br>
<br>Tony<br></div></div><br></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e0149401035887604e5316c13--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 30 Aug 2013 22:45:03 -0700 (PDT)
Raw View
------=_Part_1117_6304726.1377927903524
Content-Type: text/plain; charset=ISO-8859-1



On Friday, August 30, 2013 2:09:52 PM UTC-7, Tony V E wrote:
>
>
> - is it possible to make these cases ambiguous for optional<bool> only.
>> ie instead of picking A or B it just doesn't compile.
>>
>
>> Sure, it's possible. std::enable_if gimmicks can remove the `explicit
>> operator bool` function if T == bool.
>>
>
> removing the explicit operator would make A not compile, but B still
> compiles. I'd prefer the other way around, or neither.
>
removing just the 'explicit' part would probably make A compile, and make B
> ambiguous, but I suspect it would have other unpleasant ramifications.
>

>>
>>>  - if it is possible, is that a palatable solution?  (Note that there
>>> are alternatives for both cases - ie an explicit is_engaged() function (I
>>> think, or whatever it is called) vs an explicit dereference - "*opt ==
>>> false" or check + deref.
>>>
>>
>> *Absolutely not.*
>>
>> optional<bool> is a perfectly legitimate construct, so long as you
>> understand what it *means* and how to work with it. If you don't, then
>> you'll have problems. But it's not our job to fix that; it's your job to
>> know what you're doing.
>>
>>
> I think it is our job to make APIs that are clear and usable. C++ already
> has enough gotchas.  If coding guidelines end up saying "always explicitly
> use opt != nullopt instead of just i (opt)", then we have failed.
>

It's not clear at all that any guidelines would ever say that.

If you in some template code that takes an `optional<T>`, why is it ever
unreasonable to do this:

template<typename T>
void Func(const optional<T> &t)
{
  if(t) {...}
}

This code always means the same thing no matter what T is. Similarly:

template<typename T>
void Func(const optional<T> &t)
{
  if(t == false) {...}
}

will *fail to compile* for any T cannot be checked for equality against
bools.The == operator doesn't force a contextual conversion to bool for the
arguments; it will simply call the appropriate overloaded operator. The
`operator==` for `optional<T>`, as defined in the standard, will check to
see if `t` is disengagned. If it is, it returns false. If it isn't, it gets
the T from it and performs operator== on the value being tested against. If
that comparison is not supported, operator== cannot be instantiated and a
compiler error results.

Again, this has well-defined behavior. For any T, it will test the *
internals* of the optional against the value. There is therefore no
expectation for this code to be testing *only* whether `t` is engaged or
not.

So why would people suggest using `t != nullopt`?

Let's learn the lessons of `vector<bool>`: don't change the interface to
>> different instantiations of a template. Not unless it's because the type T
>> flat-out doesn't support that operation.
>>
>>
> vector<bool> is a good point.  I don't think not-compiling is quite as
> extreme as vector<bool>, but I still agree your point has merit.
>
> The alternative is to not do conversion to bool at all (for any T), ie
> force it to always be explicit opt == nullopt and opt != nullopt.
>

No. This issue is not substantial enough to completely break the
`optional<T>` class just because some people *might* be confused when `T ==
bool`. `optional<T>` behaves like `optional<T>` for all types T. The
behavior is only confusing for `bool` if you *expect* it to behave
differently.

This "gotcha" is a misunderstanding of concepts, not a misunderstanding of
implementation. And we should not break a class's interface because someone
might misunderstand the concept of what it means for a boolean to be
optional.

I think there is similarity here to if (ptr) vs if (ptr == nullptr) and
> other issues with 0 converting to/from pointers, and the need for nullptr.
> Is optional<> making a similar mistake?
>

That's not why we have `nullptr`. We have `nullptr` because we needed a
value which was:

1: a null-pointer constant.
2: *not also* an integer (and thus couldn't interfere in overload
resolution with integers).
3: *implicitly* convertible to any pointer type.

No such value existed in C++98/03, so we had to invent one.

I'm not totally against if (opt) and actually use if (ptr) instead of if
> (ptr == nullptr), but I think it is important to understand the "cost" of
> optional's conversion operator.  I don't think the subtlety of
> optional<bool> was considered when optional was being voted on.  Maybe
> everyone is OK with it, but I just want to know they are *aware* of it.
>
> Tony
>
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

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

<div dir=3D"ltr"><br><br>On Friday, August 30, 2013 2:09:52 PM UTC-7, Tony =
V E wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><br=
><div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex=
;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div>- =
is it possible to make these cases ambiguous for optional&lt;bool&gt; only.=
&nbsp; ie instead of picking A or B it just doesn't compile.<br>
</div></div></div></blockquote><div class=3D"gmail_quote"><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div><br>Sure, it's possible. std::enable_if=
 gimmicks can remove the `explicit operator bool` function if T =3D=3D bool=
..<br>
</div></div></blockquote><div><br></div><div>removing the explicit operator=
 would make A not compile, but B still compiles. I'd prefer the other way a=
round, or neither.<br></div></div></div></div></blockquote><blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #c=
cc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quot=
e"><div>removing just the 'explicit' part would probably make A compile, an=
d make B ambiguous, but I suspect it would have other unpleasant ramificati=
ons.<br></div></div></div></div></blockquote><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>
</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>&nbsp;</div><div=
><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex">
<div dir=3D"ltr"><div><div>
</div><div>- if it is possible, is that a palatable solution?&nbsp; (Note t=
hat there are alternatives for both cases - ie an explicit is_engaged() fun=
ction (I think, or whatever it is called) vs an explicit dereference - "*op=
t =3D=3D false" or check + deref.<br>
</div></div></div></blockquote></div><div><br><i>Absolutely not.</i><br><br=
>optional&lt;bool&gt; is a perfectly legitimate construct, so long as you u=
nderstand what it <i>means</i> and how to work with it. If you don't, then =
you'll have problems. But it's not our job to fix that; it's your job to kn=
ow what you're doing.<br>
<br></div></div></blockquote><div><br></div><div>I think it is our job to m=
ake APIs that are clear and usable. C++ already has enough gotchas.&nbsp; I=
f coding guidelines end up saying "always explicitly use opt !=3D nullopt i=
nstead of just i (opt)", then we have failed.<br></div></div></div></div></=
blockquote><div><br>It's not clear at all that any guidelines would ever sa=
y that.<br><br>If you in some template code that takes an `optional&lt;T&gt=
;`, why is it ever unreasonable to do this:<br><br><div class=3D"prettyprin=
t" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 18=
7, 187); border-style: solid; border-width: 1px; word-wrap: break-word;"><c=
ode class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">template</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"> T</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">void</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Func</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">const</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> optional</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">T</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&amp;</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify">t</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">if</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">t</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-b=
y-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></div></code></div><br>This code always means the same thing no ma=
tter what T is. Similarly:<br><br><div class=3D"prettyprint" style=3D"backg=
round-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-s=
tyle: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pret=
typrint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=
=3D"styled-by-prettify">template</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">typename</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">void=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #606;" class=3D"styled-by-prettify">Func</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color: =
#000;" class=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"styled-by-prettify">T</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-prett=
ify">&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br>&nbsp; </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">if</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">t </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">false</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">{...}</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">}</span></div></code></div><=
br>will <i>fail to compile</i> for any T cannot be checked for equality aga=
inst bools.The =3D=3D operator doesn't force a contextual conversion to boo=
l for the arguments; it will simply call the appropriate overloaded operato=
r. The `operator=3D=3D` for `optional&lt;T&gt;`, as defined in the standard=
, will check to see if `t` is disengagned. If it is, it returns false. If i=
t isn't, it gets the T from it and performs operator=3D=3D on the value bei=
ng tested against. If that comparison is not supported, operator=3D=3D cann=
ot be instantiated and a compiler error results.<br><br>Again, this has wel=
l-defined behavior. For any T, it will test the <i>internals</i> of the opt=
ional against the value. There is therefore no expectation for this code to=
 be testing <i>only</i> whether `t` is engaged or not.<br><br>So why would =
people suggest using `t !=3D nullopt`?<br><br></div><blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div=
>
</div><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Let's=
 learn the lessons of `vector&lt;bool&gt;`: don't change the interface to d=
ifferent instantiations of a template. Not unless it's because the type T f=
lat-out doesn't support that operation.<br>
<br></div></div></blockquote><div><br></div><div>vector&lt;bool&gt; is a go=
od point.&nbsp; I don't think not-compiling is quite as extreme as vector&l=
t;bool&gt;, but I still agree your point has merit.<br><br></div>The altern=
ative is to not do conversion to bool at all (for any T), ie force it to al=
ways be explicit opt =3D=3D nullopt and opt !=3D nullopt.</div></div></div>=
</blockquote><div><br>No. This issue is not substantial enough to completel=
y break the `optional&lt;T&gt;` class just because some people <i>might</i>=
 be confused when `T =3D=3D bool`. `optional&lt;T&gt;` behaves like `option=
al&lt;T&gt;` for all types T. The behavior is only confusing for `bool` if =
you <i>expect</i> it to behave differently.<br><br>This "gotcha" is a misun=
derstanding of concepts, not a misunderstanding of implementation. And we s=
hould not break a class's interface because someone might misunderstand the=
 concept of what it means for a boolean to be optional.<br><br></div><block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"=
gmail_quote">I think there is similarity here to if (ptr) vs if (ptr =3D=3D=
 nullptr) and other issues with 0 converting to/from pointers, and the need=
 for nullptr.&nbsp; Is optional&lt;&gt; making a similar mistake?<br></div>=
</div></div></blockquote><div><br>That's not why we have `nullptr`. We have=
 `nullptr` because we needed a value which was:<br><br>1: a null-pointer co=
nstant.<br>2: <i>not also</i> an integer (and thus couldn't interfere in ov=
erload resolution with integers).<br>3: <i>implicitly</i> convertible to an=
y pointer type.<br><br>No such value existed in C++98/03, so we had to inve=
nt one.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div><div class=3D"gmail_quote">I'm not totally against if (opt) a=
nd actually use if (ptr) instead of if (ptr =3D=3D nullptr), but I think it=
 is important to understand the "cost" of optional's conversion operator.&n=
bsp; I don't think the subtlety of optional&lt;bool&gt; was considered when=
 optional was being voted on.&nbsp; Maybe everyone is OK with it, but I jus=
t want to know they are *aware* of it.<br>
<br>Tony<br></div><br></div></div>
</blockquote></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1117_6304726.1377927903524--

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Sat, 31 Aug 2013 16:12:28 -0400
Raw View
--089e013d14b250c83f04e543f53d
Content-Type: text/plain; charset=ISO-8859-1

On Sat, Aug 31, 2013 at 1:45 AM, Nicol Bolas <jmckesson@gmail.com> wrote:

>
>
>> I think it is our job to make APIs that are clear and usable. C++ already
>> has enough gotchas.  If coding guidelines end up saying "always explicitly
>> use opt != nullopt instead of just i (opt)", then we have failed.
>>
>
> It's not clear at all that any guidelines would ever say that.
>

I've unfortunately had to read a lot of guidelines.  Many insist on if (ptr
== nullptr) over if (ptr), and some even if (var == false) over if
(!var).   (As it is easier to see.  Some also suggest if (not var) for
similar reasons.)
So I suspect some will suggest if (opt == nullopt) regardless of any
worries about optional<bool>.

There have also been requests for an explicit is_engaged() for optional,
for similar reasons.  (I think opt != nullopt should be good enough for
them.)



> If you in some template code that takes an `optional<T>`, why is it ever
> unreasonable to do this:
>
> template<typename T>
> void Func(const optional<T> &t)
> {
>   if(t) {...}
> }
>
> This code always means the same thing no matter what T is.
>

Agreed.  I guess template code should be fine.



> Similarly:
>
> template<typename T>
> void Func(const optional<T> &t)
> {
>   if(t == false) {...}
> }
>
> will *fail to compile* for any T cannot be checked for equality against
> bools.The == operator doesn't force a contextual conversion to bool for the
> arguments; it will simply call the appropriate overloaded operator. The
> `operator==` for `optional<T>`, as defined in the standard, will check to
> see if `t` is disengagned. If it is, it returns false. If it isn't, it gets
> the T from it and performs operator== on the value being tested against. If
> that comparison is not supported, operator== cannot be instantiated and a
> compiler error results.
>

Note that currently, optional<string>() == "foo" is not supported (the
templated function doesn't match).  I think there will be a proposal to
allow that.
Once there is, note that  optional<int>() == false *will* work, as int ==
bool is valid.



>
> Again, this has well-defined behavior. For any T, it will test the *
> internals* of the optional against the value. There is therefore no
> expectation for this code to be testing *only* whether `t` is engaged or
> not.
>
> So why would people suggest using `t != nullopt`?
>
> Let's learn the lessons of `vector<bool>`: don't change the interface to
>>> different instantiations of a template. Not unless it's because the type T
>>> flat-out doesn't support that operation.
>>>
>>>
>> vector<bool> is a good point.  I don't think not-compiling is quite as
>> extreme as vector<bool>, but I still agree your point has merit.
>>
>> The alternative is to not do conversion to bool at all (for any T), ie
>> force it to always be explicit opt == nullopt and opt != nullopt.
>>
>
> No. This issue is not substantial enough to completely break the
> `optional<T>` class just because some people *might* be confused when `T
> == bool`. `optional<T>` behaves like `optional<T>` for all types T. The
> behavior is only confusing for `bool` if you *expect* it to behave
> differently.
>

"This issue is not substantial enough".

I can understand that opinion.  If everyone agrees "meh, it is not a big
deal" then OK.


>
> This "gotcha" is a misunderstanding of concepts, not a misunderstanding of
> implementation. And we should not break a class's interface because someone
> might misunderstand the concept of what it means for a boolean to be
> optional.
>
>

I just find it odd that we took what seems to be a good interface, but
ended up with

if (foo)

!=

if (foo == true)


If everyone is comfortable with that, OK then.  One more bit of irony;
fine.  I just wanted to see if there were ways to avoid it without a high
cost to the rest of optional.  Maybe there isn't.


Tony




On Sat, Aug 31, 2013 at 1:45 AM, Nicol Bolas <jmckesson@gmail.com> wrote:

>
>
> On Friday, August 30, 2013 2:09:52 PM UTC-7, Tony V E wrote:
>>
>>
>> - is it possible to make these cases ambiguous for optional<bool> only.
>>> ie instead of picking A or B it just doesn't compile.
>>>
>>
>>> Sure, it's possible. std::enable_if gimmicks can remove the `explicit
>>> operator bool` function if T == bool.
>>>
>>
>> removing the explicit operator would make A not compile, but B still
>> compiles. I'd prefer the other way around, or neither.
>>
> removing just the 'explicit' part would probably make A compile, and make
>> B ambiguous, but I suspect it would have other unpleasant ramifications.
>>
>
>>>
>>>>  - if it is possible, is that a palatable solution?  (Note that there
>>>> are alternatives for both cases - ie an explicit is_engaged() function (I
>>>> think, or whatever it is called) vs an explicit dereference - "*opt ==
>>>> false" or check + deref.
>>>>
>>>
>>> *Absolutely not.*
>>>
>>> optional<bool> is a perfectly legitimate construct, so long as you
>>> understand what it *means* and how to work with it. If you don't, then
>>> you'll have problems. But it's not our job to fix that; it's your job to
>>> know what you're doing.
>>>
>>>
>> I think it is our job to make APIs that are clear and usable. C++ already
>> has enough gotchas.  If coding guidelines end up saying "always explicitly
>> use opt != nullopt instead of just i (opt)", then we have failed.
>>
>
> It's not clear at all that any guidelines would ever say that.
>
> If you in some template code that takes an `optional<T>`, why is it ever
> unreasonable to do this:
>
> template<typename T>
> void Func(const optional<T> &t)
> {
>   if(t) {...}
> }
>
> This code always means the same thing no matter what T is. Similarly:
>
> template<typename T>
> void Func(const optional<T> &t)
> {
>   if(t == false) {...}
> }
>
> will *fail to compile* for any T cannot be checked for equality against
> bools.The == operator doesn't force a contextual conversion to bool for the
> arguments; it will simply call the appropriate overloaded operator. The
> `operator==` for `optional<T>`, as defined in the standard, will check to
> see if `t` is disengagned. If it is, it returns false. If it isn't, it gets
> the T from it and performs operator== on the value being tested against. If
> that comparison is not supported, operator== cannot be instantiated and a
> compiler error results.
>
> Again, this has well-defined behavior. For any T, it will test the *
> internals* of the optional against the value. There is therefore no
> expectation for this code to be testing *only* whether `t` is engaged or
> not.
>
> So why would people suggest using `t != nullopt`?
>
> Let's learn the lessons of `vector<bool>`: don't change the interface to
>>> different instantiations of a template. Not unless it's because the type T
>>> flat-out doesn't support that operation.
>>>
>>>
>> vector<bool> is a good point.  I don't think not-compiling is quite as
>> extreme as vector<bool>, but I still agree your point has merit.
>>
>> The alternative is to not do conversion to bool at all (for any T), ie
>> force it to always be explicit opt == nullopt and opt != nullopt.
>>
>
> No. This issue is not substantial enough to completely break the
> `optional<T>` class just because some people *might* be confused when `T
> == bool`. `optional<T>` behaves like `optional<T>` for all types T. The
> behavior is only confusing for `bool` if you *expect* it to behave
> differently.
>
> This "gotcha" is a misunderstanding of concepts, not a misunderstanding of
> implementation. And we should not break a class's interface because someone
> might misunderstand the concept of what it means for a boolean to be
> optional.
>
> I think there is similarity here to if (ptr) vs if (ptr == nullptr) and
>> other issues with 0 converting to/from pointers, and the need for nullptr.
>> Is optional<> making a similar mistake?
>>
>
> That's not why we have `nullptr`. We have `nullptr` because we needed a
> value which was:
>
> 1: a null-pointer constant.
> 2: *not also* an integer (and thus couldn't interfere in overload
> resolution with integers).
> 3: *implicitly* convertible to any pointer type.
>
> No such value existed in C++98/03, so we had to invent one.
>
> I'm not totally against if (opt) and actually use if (ptr) instead of if
>> (ptr == nullptr), but I think it is important to understand the "cost" of
>> optional's conversion operator.  I don't think the subtlety of
>> optional<bool> was considered when optional was being voted on.  Maybe
>> everyone is OK with it, but I just want to know they are *aware* of it.
>>
>> Tony
>>
>>  --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

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

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
_quote">On Sat, Aug 31, 2013 at 1:45 AM, Nicol Bolas <span dir=3D"ltr">&lt;=
<a href=3D"mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.co=
m</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0pt 0pt 0pt 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div cla=
ss=3D"im"><div dir=3D"ltr"><div><br></div></div><blockquote class=3D"gmail_=
quote" style=3D"margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,=
204);padding-left:1ex">
<div dir=3D"ltr"><div><div class=3D"gmail_quote"><div><br></div><div>I thin=
k it is our job to make APIs that are clear and usable. C++ already has eno=
ugh gotchas.=A0 If coding guidelines end up saying &quot;always explicitly =
use opt !=3D nullopt instead of just i (opt)&quot;, then we have failed.<br=
>
</div></div></div></div></blockquote></div><div><br>It&#39;s not clear at a=
ll that any guidelines would ever say that.<br></div></div></blockquote><di=
v><br></div><div>I&#39;ve unfortunately had to read a lot of guidelines.=A0=
 Many insist on if (ptr =3D=3D nullptr) over if (ptr), and some even if (va=
r =3D=3D false) over if (!var).=A0=A0 (As it is easier to see.=A0 Some also=
 suggest if (not var) for similar reasons.)<br>
</div><div>So I suspect some will suggest if (opt =3D=3D nullopt) regardles=
s of any worries about optional&lt;bool&gt;.<br><br></div><div>There have a=
lso been requests for an explicit is_engaged() for optional, for similar re=
asons.=A0 (I think opt !=3D nullopt should be good enough for them.)<br>
<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0pt 0pt 0pt=
 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D=
"ltr"><div><br>If you in some template code that takes an `optional&lt;T&gt=
;`, why is it ever unreasonable to do this:<br>
<br><div style=3D"background-color:rgb(250,250,250);border:1px solid rgb(18=
7,187,187);word-wrap:break-word"><code></code><div><span style=3D"color:rgb=
(0,0,136)">template</span><span style=3D"color:rgb(102,102,0)">&lt;</span><=
span style=3D"color:rgb(0,0,136)">typename</span><span style> T</span><span=
 style=3D"color:rgb(102,102,0)">&gt;</span><span style><br>
</span><span style=3D"color:rgb(0,0,136)">void</span><span style> </span><s=
pan style=3D"color:rgb(102,0,102)">Func</span><span style=3D"color:rgb(102,=
102,0)">(</span><span style=3D"color:rgb(0,0,136)">const</span><span style>=
 optional</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span style=
>T</span><span style=3D"color:rgb(102,102,0)">&gt;</span><span style> </spa=
n><span style=3D"color:rgb(102,102,0)">&amp;</span><span style>t</span><spa=
n style=3D"color:rgb(102,102,0)">)</span><span style><br>
</span><span style=3D"color:rgb(102,102,0)">{</span><span style><br>=A0 </s=
pan><span style=3D"color:rgb(0,0,136)">if</span><span style=3D"color:rgb(10=
2,102,0)">(</span><span style>t</span><span style=3D"color:rgb(102,102,0)">=
)</span><span style> </span><span style=3D"color:rgb(102,102,0)">{...}</spa=
n><span style><br>
</span><span style=3D"color:rgb(102,102,0)">}</span></div></div><br>This co=
de always means the same thing no matter what T is.</div></div></blockquote=
><div><br></div><div>Agreed.=A0 I guess template code should be fine.<br><b=
r>
=A0<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0pt 0pt 0pt =
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"=
ltr"><div> Similarly:<br><br><div style=3D"background-color:rgb(250,250,250=
);border:1px solid rgb(187,187,187);word-wrap:break-word">
<code></code><div><span style=3D"color:rgb(0,0,136)">template</span><span s=
tyle=3D"color:rgb(102,102,0)">&lt;</span><span style=3D"color:rgb(0,0,136)"=
>typename</span><span style> T</span><span style=3D"color:rgb(102,102,0)">&=
gt;</span><span style><br>
</span><span style=3D"color:rgb(0,0,136)">void</span><span style> </span><s=
pan style=3D"color:rgb(102,0,102)">Func</span><span style=3D"color:rgb(102,=
102,0)">(</span><span style=3D"color:rgb(0,0,136)">const</span><span style>=
 optional</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span style=
>T</span><span style=3D"color:rgb(102,102,0)">&gt;</span><span style> </spa=
n><span style=3D"color:rgb(102,102,0)">&amp;</span><span style>t</span><spa=
n style=3D"color:rgb(102,102,0)">)</span><span style><br>
</span><span style=3D"color:rgb(102,102,0)">{</span><span style><br>=A0 </s=
pan><span style=3D"color:rgb(0,0,136)">if</span><span style=3D"color:rgb(10=
2,102,0)">(</span><span style>t </span><span style=3D"color:rgb(102,102,0)"=
>=3D=3D</span><span style> </span><span style=3D"color:rgb(0,0,136)">false<=
/span><span style=3D"color:rgb(102,102,0)">)</span><span style> </span><spa=
n style=3D"color:rgb(102,102,0)">{...}</span><span style><br>
</span><span style=3D"color:rgb(102,102,0)">}</span></div></div><br>will <i=
>fail to compile</i> for any T cannot be checked for equality against bools=
..The =3D=3D operator doesn&#39;t force a contextual conversion to bool for =
the arguments; it will simply call the appropriate overloaded operator. The=
 `operator=3D=3D` for `optional&lt;T&gt;`, as defined in the standard, will=
 check to see if `t` is disengagned. If it is, it returns false. If it isn&=
#39;t, it gets the T from it and performs operator=3D=3D on the value being=
 tested against. If that comparison is not supported, operator=3D=3D cannot=
 be instantiated and a compiler error results.<br>
</div></div></blockquote><div><br></div><div>Note that currently, optional&=
lt;string&gt;() =3D=3D &quot;foo&quot; is not supported (the templated func=
tion doesn&#39;t match).=A0 I think there will be a proposal to allow that.=
<br>
Once there is, note that=A0 optional&lt;int&gt;() =3D=3D false *will* work,=
 as int =3D=3D bool is valid.<br><br>=A0<br></div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,20=
4,204);padding-left:1ex">
<div dir=3D"ltr"><div><br>Again, this has well-defined behavior. For any T,=
 it will test the <i>internals</i> of the optional against the value. There=
 is therefore no expectation for this code to be testing <i>only</i> whethe=
r `t` is engaged or not.<br>
<br>So why would people suggest using `t !=3D nullopt`?<br><br></div><div c=
lass=3D"im"><blockquote class=3D"gmail_quote" style=3D"margin:0pt 0pt 0pt 0=
..8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"l=
tr"><div>
<div class=3D"gmail_quote"><div>
</div><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0pt 0pt =
0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=
=3D"ltr"><div>Let&#39;s learn the lessons of `vector&lt;bool&gt;`: don&#39;=
t change the interface to different instantiations of a template. Not unles=
s it&#39;s because the type T flat-out doesn&#39;t support that operation.<=
br>

<br></div></div></blockquote><div><br></div><div>vector&lt;bool&gt; is a go=
od point.=A0 I don&#39;t think not-compiling is quite as extreme as vector&=
lt;bool&gt;, but I still agree your point has merit.<br><br></div>The alter=
native is to not do conversion to bool at all (for any T), ie force it to a=
lways be explicit opt =3D=3D nullopt and opt !=3D nullopt.</div>
</div></div></blockquote></div><div><br>No. This issue is not substantial e=
nough to completely break the `optional&lt;T&gt;` class just because some p=
eople <i>might</i> be confused when `T =3D=3D bool`. `optional&lt;T&gt;` be=
haves like `optional&lt;T&gt;` for all types T. The behavior is only confus=
ing for `bool` if you <i>expect</i> it to behave differently.<br>
</div></div></blockquote><div><br></div><div>&quot;This issue is not substa=
ntial enough&quot;.<br><br></div><div>I can understand that opinion.=A0 If =
everyone agrees &quot;meh, it is not a big deal&quot; then OK.<br>=A0<br></=
div>
<blockquote class=3D"gmail_quote" style=3D"margin:0pt 0pt 0pt 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div><br=
>This &quot;gotcha&quot; is a misunderstanding of concepts, not a misunders=
tanding of implementation. And we should not break a class&#39;s interface =
because someone might misunderstand the concept of what it means for a bool=
ean to be optional.<br>
<br></div></div></blockquote><div><br></div><br></div><div class=3D"gmail_q=
uote">I just find it odd that we took what seems to be a good interface, bu=
t ended up with<br><br></div><div class=3D"gmail_quote">if (foo)<br><br>!=
=3D<br>
<br></div><div class=3D"gmail_quote">if (foo =3D=3D true)<br><br></div><div=
 class=3D"gmail_quote"><br></div><div class=3D"gmail_quote">If everyone is =
comfortable with that, OK then.=A0 One more bit of irony; fine.=A0 I just w=
anted to see if there were ways to avoid it without a high cost to the rest=
 of optional.=A0 Maybe there isn&#39;t.<br>
<br><br></div><div class=3D"gmail_quote">Tony<br></div><div class=3D"gmail_=
quote"><br></div><br></div></div><div class=3D"gmail_extra"><br><br><div cl=
ass=3D"gmail_quote">On Sat, Aug 31, 2013 at 1:45 AM, Nicol Bolas <span dir=
=3D"ltr">&lt;<a href=3D"mailto:jmckesson@gmail.com" target=3D"_blank">jmcke=
sson@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=3D"im"><br><br>O=
n Friday, August 30, 2013 2:09:52 PM UTC-7, Tony V E wrote:<blockquote clas=
s=3D"gmail_quote" style=3D"margin:0pt 0pt 0pt 0.8ex;border-left:1px solid r=
gb(204,204,204);padding-left:1ex">
<div dir=3D"ltr"><br><div><blockquote class=3D"gmail_quote" style=3D"margin=
:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"=
><div dir=3D"ltr"><div><div>- is it possible to make these cases ambiguous =
for optional&lt;bool&gt; only.=A0 ie instead of picking A or B it just does=
n&#39;t compile.<br>

</div></div></div></blockquote><div class=3D"gmail_quote"><blockquote class=
=3D"gmail_quote" style=3D"margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div><br>Sure, it&#39;s p=
ossible. std::enable_if gimmicks can remove the `explicit operator bool` fu=
nction if T =3D=3D bool.<br>

</div></div></blockquote><div><br></div><div>removing the explicit operator=
 would make A not compile, but B still compiles. I&#39;d prefer the other w=
ay around, or neither.<br></div></div></div></div></blockquote><blockquote =
class=3D"gmail_quote" style=3D"margin:0pt 0pt 0pt 0.8ex;border-left:1px sol=
id rgb(204,204,204);padding-left:1ex">
<div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>removing just the &#3=
9;explicit&#39; part would probably make A compile, and make B ambiguous, b=
ut I suspect it would have other unpleasant ramifications.<br></div></div><=
/div>
</div></blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0pt 0p=
t 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div d=
ir=3D"ltr"><div><div class=3D"gmail_quote"><div>
</div><blockquote class=3D"gmail_quote" style=3D"margin:0pt 0pt 0pt 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><d=
iv>=A0</div><div><blockquote class=3D"gmail_quote" style=3D"margin:0pt 0pt =
0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<div dir=3D"ltr"><div><div>
</div><div>- if it is possible, is that a palatable solution?=A0 (Note that=
 there are alternatives for both cases - ie an explicit is_engaged() functi=
on (I think, or whatever it is called) vs an explicit dereference - &quot;*=
opt =3D=3D false&quot; or check + deref.<br>

</div></div></div></blockquote></div><div><br><i>Absolutely not.</i><br><br=
>optional&lt;bool&gt; is a perfectly legitimate construct, so long as you u=
nderstand what it <i>means</i> and how to work with it. If you don&#39;t, t=
hen you&#39;ll have problems. But it&#39;s not our job to fix that; it&#39;=
s your job to know what you&#39;re doing.<br>

<br></div></div></blockquote><div><br></div><div>I think it is our job to m=
ake APIs that are clear and usable. C++ already has enough gotchas.=A0 If c=
oding guidelines end up saying &quot;always explicitly use opt !=3D nullopt=
 instead of just i (opt)&quot;, then we have failed.<br>
</div></div></div></div></blockquote></div><div><br>It&#39;s not clear at a=
ll that any guidelines would ever say that.<br><br>If you in some template =
code that takes an `optional&lt;T&gt;`, why is it ever unreasonable to do t=
his:<br>
<br><div style=3D"background-color:rgb(250,250,250);border:1px solid rgb(18=
7,187,187);word-wrap:break-word"><code></code><div><span style=3D"color:rgb=
(0,0,136)">template</span><span style=3D"color:rgb(102,102,0)">&lt;</span><=
span style=3D"color:rgb(0,0,136)">typename</span><span style> T</span><span=
 style=3D"color:rgb(102,102,0)">&gt;</span><span style><br>
</span><span style=3D"color:rgb(0,0,136)">void</span><span style> </span><s=
pan style=3D"color:rgb(102,0,102)">Func</span><span style=3D"color:rgb(102,=
102,0)">(</span><span style=3D"color:rgb(0,0,136)">const</span><span style>=
 optional</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span style=
>T</span><span style=3D"color:rgb(102,102,0)">&gt;</span><span style> </spa=
n><span style=3D"color:rgb(102,102,0)">&amp;</span><span style>t</span><spa=
n style=3D"color:rgb(102,102,0)">)</span><span style><br>
</span><span style=3D"color:rgb(102,102,0)">{</span><span style><br>=A0 </s=
pan><span style=3D"color:rgb(0,0,136)">if</span><span style=3D"color:rgb(10=
2,102,0)">(</span><span style>t</span><span style=3D"color:rgb(102,102,0)">=
)</span><span style> </span><span style=3D"color:rgb(102,102,0)">{...}</spa=
n><span style><br>
</span><span style=3D"color:rgb(102,102,0)">}</span></div></div><br>This co=
de always means the same thing no matter what T is. Similarly:<br><br><div =
style=3D"background-color:rgb(250,250,250);border:1px solid rgb(187,187,187=
);word-wrap:break-word">
<code></code><div><span style=3D"color:rgb(0,0,136)">template</span><span s=
tyle=3D"color:rgb(102,102,0)">&lt;</span><span style=3D"color:rgb(0,0,136)"=
>typename</span><span style> T</span><span style=3D"color:rgb(102,102,0)">&=
gt;</span><span style><br>
</span><span style=3D"color:rgb(0,0,136)">void</span><span style> </span><s=
pan style=3D"color:rgb(102,0,102)">Func</span><span style=3D"color:rgb(102,=
102,0)">(</span><span style=3D"color:rgb(0,0,136)">const</span><span style>=
 optional</span><span style=3D"color:rgb(102,102,0)">&lt;</span><span style=
>T</span><span style=3D"color:rgb(102,102,0)">&gt;</span><span style> </spa=
n><span style=3D"color:rgb(102,102,0)">&amp;</span><span style>t</span><spa=
n style=3D"color:rgb(102,102,0)">)</span><span style><br>
</span><span style=3D"color:rgb(102,102,0)">{</span><span style><br>=A0 </s=
pan><span style=3D"color:rgb(0,0,136)">if</span><span style=3D"color:rgb(10=
2,102,0)">(</span><span style>t </span><span style=3D"color:rgb(102,102,0)"=
>=3D=3D</span><span style> </span><span style=3D"color:rgb(0,0,136)">false<=
/span><span style=3D"color:rgb(102,102,0)">)</span><span style> </span><spa=
n style=3D"color:rgb(102,102,0)">{...}</span><span style><br>
</span><span style=3D"color:rgb(102,102,0)">}</span></div></div><br>will <i=
>fail to compile</i> for any T cannot be checked for equality against bools=
..The =3D=3D operator doesn&#39;t force a contextual conversion to bool for =
the arguments; it will simply call the appropriate overloaded operator. The=
 `operator=3D=3D` for `optional&lt;T&gt;`, as defined in the standard, will=
 check to see if `t` is disengagned. If it is, it returns false. If it isn&=
#39;t, it gets the T from it and performs operator=3D=3D on the value being=
 tested against. If that comparison is not supported, operator=3D=3D cannot=
 be instantiated and a compiler error results.<br>
<br>Again, this has well-defined behavior. For any T, it will test the <i>i=
nternals</i> of the optional against the value. There is therefore no expec=
tation for this code to be testing <i>only</i> whether `t` is engaged or no=
t.<br>
<br>So why would people suggest using `t !=3D nullopt`?<br><br></div><div c=
lass=3D"im"><blockquote class=3D"gmail_quote" style=3D"margin:0pt 0pt 0pt 0=
..8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"l=
tr"><div>
<div class=3D"gmail_quote"><div>
</div><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0pt 0pt =
0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=
=3D"ltr"><div>Let&#39;s learn the lessons of `vector&lt;bool&gt;`: don&#39;=
t change the interface to different instantiations of a template. Not unles=
s it&#39;s because the type T flat-out doesn&#39;t support that operation.<=
br>

<br></div></div></blockquote><div><br></div><div>vector&lt;bool&gt; is a go=
od point.=A0 I don&#39;t think not-compiling is quite as extreme as vector&=
lt;bool&gt;, but I still agree your point has merit.<br><br></div>The alter=
native is to not do conversion to bool at all (for any T), ie force it to a=
lways be explicit opt =3D=3D nullopt and opt !=3D nullopt.</div>
</div></div></blockquote></div><div><br>No. This issue is not substantial e=
nough to completely break the `optional&lt;T&gt;` class just because some p=
eople <i>might</i> be confused when `T =3D=3D bool`. `optional&lt;T&gt;` be=
haves like `optional&lt;T&gt;` for all types T. The behavior is only confus=
ing for `bool` if you <i>expect</i> it to behave differently.<br>
<br>This &quot;gotcha&quot; is a misunderstanding of concepts, not a misund=
erstanding of implementation. And we should not break a class&#39;s interfa=
ce because someone might misunderstand the concept of what it means for a b=
oolean to be optional.<br>
<br></div><div class=3D"im"><blockquote class=3D"gmail_quote" style=3D"marg=
in:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1e=
x"><div dir=3D"ltr"><div><div class=3D"gmail_quote">I think there is simila=
rity here to if (ptr) vs if (ptr =3D=3D nullptr) and other issues with 0 co=
nverting to/from pointers, and the need for nullptr.=A0 Is optional&lt;&gt;=
 making a similar mistake?<br>
</div></div></div></blockquote></div><div><br>That&#39;s not why we have `n=
ullptr`. We have `nullptr` because we needed a value which was:<br><br>1: a=
 null-pointer constant.<br>2: <i>not also</i> an integer (and thus couldn&#=
39;t interfere in overload resolution with integers).<br>
3: <i>implicitly</i> convertible to any pointer type.<br><br>No such value =
existed in C++98/03, so we had to invent one.<br><br></div><div class=3D"im=
"><blockquote class=3D"gmail_quote" style=3D"margin:0pt 0pt 0pt 0.8ex;borde=
r-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir=3D"ltr"><div><div class=3D"gmail_quote">I&#39;m not totally agains=
t if (opt) and actually use if (ptr) instead of if (ptr =3D=3D nullptr), bu=
t I think it is important to understand the &quot;cost&quot; of optional&#3=
9;s conversion operator.=A0 I don&#39;t think the subtlety of optional&lt;b=
ool&gt; was considered when optional was being voted on.=A0 Maybe everyone =
is OK with it, but I just want to know they are *aware* of it.<br>

<br>Tony<br></div><br></div></div>
</blockquote></div></div><div class=3D"HOEnZb"><div class=3D"h5">

<p></p>

-- <br>
=A0<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></div><br></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--089e013d14b250c83f04e543f53d--

.


Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Mon, 2 Sep 2013 01:48:42 -0700 (PDT)
Raw View
------=_Part_2841_23673605.1378111722268
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable



W dniu sobota, 31 sierpnia 2013 00:05:38 UTC+2 u=BFytkownik Tony V E napisa=
=B3:
>
>
>
>
> On Fri, Aug 30, 2013 at 5:13 PM, Jeffrey Yasskin <jyas...@google.com<java=
script:>
> > wrote:
>
>> > Maybe everyone is OK with it, but I just want to know they are *aware*=
=20
>> of it.
>>
>> It was mentioned in the paper
>> (
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3527.html#ratio=
nale.bool_conversion
>> ),
>> just not discussed to death like some other issues.
>
>
> :-)
>
> =20
>
>> I think people
>> were adequately aware of it.
>>
>>
> I don't think the paper highlights the problem clearly.  ie the paper say=
s
>
> " types bool*, unique_ptr<bool>, shared_ptr<bool> suffer from the same=20
> potential problem,  "
>
> yet they do not, because they do not have the mixed relational operators.
>
> So for the above types,
>
>     if (boolptr)
>
> and
>
>     if (boolptr =3D=3D false)
>
> *ARE* the same.
>
> Yes, for the above types, there is some confusion as to
>
>    if (boolptr)
>
> did the programmer mean...
>
>     if (*boolptr)
>
> ...?  But there isn't the flat-out "contradiction" of=20
>
>      optional<bool> boolopt =3D false;
>
>      assert( !boolopt !=3D (boolopt =3D=3D false) );
>
> that only optional<bool> has.
>
> (I think. Or did I miss mixed-relational-operators in smart pointers or=
=20
> something?)
>

Your analysis is correct. std::optional is the only type in STD that=20
displays these semantics.=20

The "mixed" comparison (between optional<T> and T) is a natural consequence=
=20
of allowing the implicit construction of optional<T> from T (the comparison=
=20
then works immediately and one would have to artificially "poison" the=20
rel-ops). In order to gracefully fix the problem you see, we would have to=
=20
prevent the implicit conversion from T to optional<T>, which we believed=20
was too drastic reduction of the interface.

Regards,
&rzej=20

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

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

<div dir=3D"ltr"><br><br>W dniu sobota, 31 sierpnia 2013 00:05:38 UTC+2 u=
=BFytkownik Tony V E napisa=B3:<blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
><div dir=3D"ltr"><br><div><br><br><div class=3D"gmail_quote">On Fri, Aug 3=
0, 2013 at 5:13 PM, Jeffrey Yasskin <span dir=3D"ltr">&lt;<a href=3D"javasc=
ript:" target=3D"_blank" gdf-obfuscated-mailto=3D"UFE7h_bnXa0J">jyas...@goo=
gle.com</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><div>&gt; Maybe everyone =
is OK with it, but I just want to know they are *aware* of it.<br>

<br>
</div>It was mentioned in the paper<br>
(<a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3527.h=
tml#rationale.bool_conversion" target=3D"_blank">http://www.open-std.org/jt=
c1/<wbr>sc22/wg21/docs/papers/2013/<wbr>n3527.html#rationale.bool_<wbr>conv=
ersion</a>),<br>

just not discussed to death like some other issues.</blockquote><div><br>:-=
)<br><br>&nbsp;<br></div><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">=
 I think people<br>

were adequately aware of it.<br>
<div><div><br></div></div></blockquote><div><br></div><div>I don't think th=
e paper highlights the problem clearly.&nbsp; ie the paper says<br><br>" ty=
pes <code>bool*</code>, <code>unique_ptr&lt;bool&gt;</code>, <code>shared_p=
tr&lt;bool&gt;</code> suffer from the same potential problem,&nbsp; "<br>
<br></div><div>yet they do not, because they do not have the mixed relation=
al operators.<br><br></div><div>So for the above types,<br></div><br><div>&=
nbsp;&nbsp;&nbsp; if (boolptr)<br><br></div><div>and<br><br>&nbsp;&nbsp;&nb=
sp; if (boolptr =3D=3D false)<br>
<br></div><div>*ARE* the same.<br><br></div><div>Yes, for the above types, =
there is some confusion as to<br><br></div><div>&nbsp;&nbsp; if (boolptr)<b=
r><br>did the programmer mean...<br><br>&nbsp;&nbsp;&nbsp; if (*boolptr)<br=
><br></div><div>...?&nbsp; But there isn't the flat-out "contradiction" of =
<br>
<br></div><div>&nbsp;&nbsp;&nbsp;&nbsp; optional&lt;bool&gt; boolopt =3D fa=
lse;<br><br></div><div>&nbsp;&nbsp;&nbsp;&nbsp; assert( !boolopt !=3D (bool=
opt =3D=3D false) );<br><br></div><div>that only optional&lt;bool&gt; has.<=
br><br></div><div>(I think. Or did I miss mixed-relational-operators in sma=
rt pointers or something?)<br></div></div></div></div></blockquote><div><br=
>Your analysis is correct. std::optional is the only type in STD that displ=
ays these semantics. <br><br>The "mixed" comparison (between optional&lt;T&=
gt; and T) is a natural consequence of allowing the implicit construction o=
f optional&lt;T&gt; from T (the comparison then works immediately and one w=
ould have to artificially "poison" the rel-ops). In order to gracefully fix=
 the problem you see, we would have to prevent the implicit conversion from=
 T to optional&lt;T&gt;, which we believed was too drastic reduction of the=
 interface.<br><br>Regards,<br>&amp;rzej <br></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_2841_23673605.1378111722268--

.


Author: Zhihao Yuan <zy@miator.net>
Date: Tue, 3 Sep 2013 12:35:25 -0400
Raw View
--047d7b677678a0b97804e57d4619
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Sep 2, 2013 4:48 AM, "Andrzej Krzemie=C5=84ski" <akrzemi1@gmail.com> wro=
te:
> The "mixed" comparison (between optional<T> and T) is a natural
consequence of allowing the implicit construction of optional<T> from T
(the comparison then works immediately and one would have to artificially
"poison" the rel-ops).

I agree.  However, I don't think the explicit bool
operator is natural.  opt.empty() looks less
confusing IMHO.  100% copy of a pointer-like
interface is not needed.  For example, iterator is
also pointer-like, but it has no such interface.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

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

<p>On Sep 2, 2013 4:48 AM, &quot;Andrzej Krzemie=C5=84ski&quot; &lt;<a href=
=3D"mailto:akrzemi1@gmail.com">akrzemi1@gmail.com</a>&gt; wrote:<br>
&gt; The &quot;mixed&quot; comparison (between optional&lt;T&gt; and T) is =
a natural consequence of allowing the implicit construction of optional&lt;=
T&gt; from T (the comparison then works immediately and one would have to a=
rtificially &quot;poison&quot; the rel-ops).</p>

<p>I agree.=C2=A0 However, I don&#39;t think the explicit bool<br>
operator is natural.=C2=A0 opt.empty() looks less<br>
confusing IMHO.=C2=A0 100% copy of a pointer-like<br>
interface is not needed.=C2=A0 For example, iterator is<br>
also pointer-like, but it has no such interface.</p>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7b677678a0b97804e57d4619--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 3 Sep 2013 15:57:18 -0700 (PDT)
Raw View
------=_Part_1822_2604.1378249038150
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



On Tuesday, September 3, 2013 9:35:25 AM UTC-7, Zhihao Yuan wrote:
>
> On Sep 2, 2013 4:48 AM, "Andrzej Krzemie=C5=84ski" <akrz...@gmail.com<jav=
ascript:>>=20
> wrote:
> > The "mixed" comparison (between optional<T> and T) is a natural=20
> consequence of allowing the implicit construction of optional<T> from T=
=20
> (the comparison then works immediately and one would have to artificially=
=20
> "poison" the rel-ops).
>
> I agree.  However, I don't think the explicit bool
> operator is natural.  opt.empty() looks less
> confusing IMHO.  100% copy of a pointer-like
> interface is not needed.  For example, iterator is
> also pointer-like, but it has no such interface.
>

`iterator` doesn't have that interface because it *can't* have that=20
interface. It can't detect whether it's out of range, valid, or empty at=20
all.

There are plenty of types in the standard library that detect validity by=
=20
`explicit operator bool`.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

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

<div dir=3D"ltr"><br><br>On Tuesday, September 3, 2013 9:35:25 AM UTC-7, Zh=
ihao Yuan wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><p>On Sep 2, 2=
013 4:48 AM, "Andrzej Krzemie=C5=84ski" &lt;<a href=3D"javascript:" target=
=3D"_blank" gdf-obfuscated-mailto=3D"WAMLMSkttq4J">akrz...@gmail.com</a>&gt=
; wrote:<br>
&gt; The "mixed" comparison (between optional&lt;T&gt; and T) is a natural =
consequence of allowing the implicit construction of optional&lt;T&gt; from=
 T (the comparison then works immediately and one would have to artificiall=
y "poison" the rel-ops).</p>

<p>I agree.&nbsp; However, I don't think the explicit bool<br>
operator is natural.&nbsp; opt.empty() looks less<br>
confusing IMHO.&nbsp; 100% copy of a pointer-like<br>
interface is not needed.&nbsp; For example, iterator is<br>
also pointer-like, but it has no such interface.</p></blockquote><div><br>`=
iterator` doesn't have that interface because it <i>can't</i> have that int=
erface. It can't detect whether it's out of range, valid, or empty at all.<=
br><br>There are plenty of types in the standard library that detect validi=
ty by `explicit operator bool`.<br></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1822_2604.1378249038150--

.


Author: =?UTF-8?Q?Andrzej_Krzemie=C5=84ski?= <akrzemi1@gmail.com>
Date: Wed, 4 Sep 2013 06:36:18 -0700 (PDT)
Raw View
------=_Part_287_3438612.1378301778491
Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable



W dniu =B6roda, 4 wrze=B6nia 2013 00:57:18 UTC+2 u=BFytkownik Nicol Bolas n=
apisa=B3:
>
>
>
> On Tuesday, September 3, 2013 9:35:25 AM UTC-7, Zhihao Yuan wrote:
>>
>> On Sep 2, 2013 4:48 AM, "Andrzej Krzemie=F1ski" <akrz...@gmail.com> wrot=
e:
>> > The "mixed" comparison (between optional<T> and T) is a natural=20
>> consequence of allowing the implicit construction of optional<T> from T=
=20
>> (the comparison then works immediately and one would have to artificiall=
y=20
>> "poison" the rel-ops).
>>
>> I agree.  However, I don't think the explicit bool
>> operator is natural.  opt.empty() looks less
>> confusing IMHO.  100% copy of a pointer-like
>> interface is not needed.  For example, iterator is
>> also pointer-like, but it has no such interface.
>>
>
> `iterator` doesn't have that interface because it *can't* have that=20
> interface. It can't detect whether it's out of range, valid, or empty at=
=20
> all.
>
> There are plenty of types in the standard library that detect validity by=
=20
> `explicit operator bool`.
>

Agreed. explicit operator bool is a well established idiom in C++, and=20
removing it would severely limit the interface of *std::optional*. We=20
expect the following usages:=20

if (std::optional<int> oi =3D getValue())
  use (*oi);
else
  dosomethingElse ();

Personally, I would be more comfortable removing the assignment, conversion=
=20
and comparison with *T*. But we are talking about preferences now, I guess.

As a side note, but in response to the original question: recently, I had=
=20
to use *boost::optional<bool>* to indicate a bool that has a determinate=20
value which has not yet been computed/assigned. *boost::tribool* was not=20
the right abstraction, because logical operators have inadequate semantics=
=20
for my usage. At some point I wanted to check if the value of such object=
=20
was set to true. That is, being set to false, or not being set yet, I=20
considered the same case: not being set to true. Mixed comparison was just=
=20
the right thing for the job: *if (ob =3D=3D true)*. It didn't look ambiguou=
s,=20
and I would certainly never think it means "if *ob *is initialized" because=
=20
one uses *boost::none* for this. But perhaps this intuition varies with=20
individuals.

boost::tribool also provides unintuitive behaviour because *!(t =3D=3D true=
)*is not same as=20
*(t =3D=3D false)*. And similarly:
*if (t) yes(); else no();* // is not same as
*if (!t) no(); else yes(); *

Regards,
&rzej

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

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

<div dir=3D"ltr"><br><br>W dniu =B6roda, 4 wrze=B6nia 2013 00:57:18 UTC+2 u=
=BFytkownik Nicol Bolas napisa=B3:<blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><br><br>On Tuesday, September 3, 2013 9:35:25 AM UTC=
-7, Zhihao Yuan wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><p>On Sep 2, =
2013 4:48 AM, "Andrzej Krzemie=F1ski" &lt;<a>akrz...@gmail.com</a>&gt; wrot=
e:<br>
&gt; The "mixed" comparison (between optional&lt;T&gt; and T) is a natural =
consequence of allowing the implicit construction of optional&lt;T&gt; from=
 T (the comparison then works immediately and one would have to artificiall=
y "poison" the rel-ops).</p>

<p>I agree.&nbsp; However, I don't think the explicit bool<br>
operator is natural.&nbsp; opt.empty() looks less<br>
confusing IMHO.&nbsp; 100% copy of a pointer-like<br>
interface is not needed.&nbsp; For example, iterator is<br>
also pointer-like, but it has no such interface.</p></blockquote><div><br>`=
iterator` doesn't have that interface because it <i>can't</i> have that int=
erface. It can't detect whether it's out of range, valid, or empty at all.<=
br><br>There are plenty of types in the standard library that detect validi=
ty by `explicit operator bool`.<br></div></div></blockquote><div><br>Agreed=
.. explicit operator bool is a well established idiom in C++, and removing i=
t would severely limit the interface of <b>std::optional</b>. We expect the=
 following usages: <br><br>if (std::optional&lt;int&gt; oi =3D getValue())<=
br>&nbsp; use (*oi);<br>else<br>&nbsp; dosomethingElse ();<br></div><div><b=
r>Personally, I would be more comfortable removing the assignment, conversi=
on and comparison with <b>T</b>. But we are talking about preferences now, =
I guess.<br><br>As a side note, but in response to the original question: r=
ecently, I had to use <b>boost::optional&lt;bool&gt;</b> to indicate a bool=
 that has a determinate value which has not yet been computed/assigned. <b>=
boost::tribool</b> was not the right abstraction, because logical operators=
 have inadequate semantics for my usage. At some point I wanted to check if=
 the value of such object was set to true. That is, being set to false, or =
not being set yet, I considered the same case: not being set to true. Mixed=
 comparison was just the right thing for the job: <b>if (ob =3D=3D true)</b=
>. It didn't look ambiguous, and I would certainly never think it means "if=
 <b>ob </b>is initialized" because one uses <b>boost::none</b> for this. Bu=
t perhaps this intuition varies with individuals.<br><br>boost::tribool als=
o provides unintuitive behaviour because <b>!(t =3D=3D true)</b> is not sam=
e as <b>(t =3D=3D false)</b>. And similarly:<br><b>if (t) yes(); else no();=
</b> // is not same as<br><b>if (!t) no(); else yes(); </b><br><br>Regards,=
<br>&amp;rzej<br></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_287_3438612.1378301778491--

.


Author: Bjorn Reese <breese@mail1.stofanet.dk>
Date: Wed, 04 Sep 2013 16:07:13 +0200
Raw View
On 09/04/2013 03:36 PM, Andrzej Krzemie=C5=84ski wrote:

> As a side note, but in response to the original question: recently, I
> had to use *boost::optional<bool>* to indicate a bool that has a
> determinate value which has not yet been computed/assigned.
> *boost::tribool* was not the right abstraction, because logical
> operators have inadequate semantics for my usage. At some point I wanted

FYI, faced with the same problem, I wrote a simple tribool where you can
use traits to determine the results of logical operators:

   https://github.com/breese/tribool

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.