2016-09-17 01:25:12 +02:00
< html >
< head >
2020-10-24 17:17:10 +02:00
< meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" >
2016-09-17 01:25:12 +02:00
< title > Gotchas</ title >
< link rel = "stylesheet" href = "../../../../../../doc/src/boostbook.css" type = "text/css" >
2018-03-24 00:04:15 +01:00
< meta name = "generator" content = "DocBook XSL Stylesheets Vsnapshot" >
2016-09-17 01:25:12 +02:00
< link rel = "home" href = "../../index.html" title = "Boost.Optional" >
< link rel = "up" href = "../../optional/tutorial.html" title = "Tutorial" >
< link rel = "prev" href = "in_place_factories.html" title = "In-Place Factories" >
< link rel = "next" href = "gotchas/moved_from__optional_.html" title = "Moved-from optional" >
</ head >
< body bgcolor = "white" text = "black" link = "#0000FF" vlink = "#840084" alink = "#0000FF" >
< table cellpadding = "2" width = "100%" >< tr >
< td valign = "top" >< img alt = "Boost C++ Libraries" width = "277" height = "86" src = "../../../../../../boost.png" ></ td >
< td align = "center" >< a href = "../../../../../../index.html" > Home</ a ></ td >
< td align = "center" >< a href = "../../../../../../libs/libraries.htm" > Libraries</ a ></ td >
< td align = "center" >< a href = "http://www.boost.org/users/people.html" > People</ a ></ td >
< td align = "center" >< a href = "http://www.boost.org/users/faq.html" > FAQ</ a ></ td >
< td align = "center" >< a href = "../../../../../../more/index.htm" > More</ a ></ td >
</ tr ></ table >
< hr >
< div class = "spirit-nav" >
< a accesskey = "p" href = "in_place_factories.html" >< img src = "../../../../../../doc/src/images/prev.png" alt = "Prev" ></ a >< a accesskey = "u" href = "../../optional/tutorial.html" >< img src = "../../../../../../doc/src/images/up.png" alt = "Up" ></ a >< a accesskey = "h" href = "../../index.html" >< img src = "../../../../../../doc/src/images/home.png" alt = "Home" ></ a >< a accesskey = "n" href = "gotchas/moved_from__optional_.html" >< img src = "../../../../../../doc/src/images/next.png" alt = "Next" ></ a >
</ div >
< div class = "section" >
< div class = "titlepage" >< div >< div >< h3 class = "title" >
< a name = "boost_optional.tutorial.gotchas" ></ a >< a class = "link" href = "gotchas.html" title = "Gotchas" > Gotchas</ a >
</ h3 ></ div ></ div ></ div >
< div class = "section" >
< div class = "titlepage" >< div >< div >< h4 class = "title" >
< a name = "boost_optional.tutorial.gotchas.a_note_about_optional_bool_" ></ a >< a class = "link" href = "gotchas.html#boost_optional.tutorial.gotchas.a_note_about_optional_bool_" title = "A note about optional<bool>" > A
note about optional< bool> </ a >
</ h4 ></ div ></ div ></ div >
< p >
< code class = "computeroutput" >< span class = "identifier" > optional</ span >< span class = "special" > < </ span >< span class = "keyword" > bool</ span >< span class = "special" > > </ span ></ code >
should be used with special caution and consideration.
</ p >
< p >
First, it is functionally similar to a tristate boolean (false, maybe,
2020-10-24 17:17:10 +02:00
true) —such as < a href = "../../../../../../doc/html/tribool.html" target = "_top" > boost::tribool</ a > —
2016-09-17 01:25:12 +02:00
except that in a tristate boolean, the maybe state < span class = "underline" > represents
a valid value</ span > , unlike the corresponding state of an uninitialized
< code class = "computeroutput" >< span class = "identifier" > optional</ span >< span class = "special" > < </ span >< span class = "keyword" > bool</ span >< span class = "special" > > </ span ></ code > .
It should be carefully considered if an < code class = "computeroutput" >< span class = "identifier" > optional</ span >< span class = "special" > < </ span >< span class = "keyword" > bool</ span >< span class = "special" > > </ span ></ code > instead of a < code class = "computeroutput" >< span class = "identifier" > tribool</ span ></ code >
is really needed.
</ p >
< p >
Second, although < code class = "computeroutput" >< span class = "identifier" > optional</ span >< span class = "special" > <> </ span ></ code > provides a contextual conversion
to < code class = "computeroutput" >< span class = "keyword" > bool</ span ></ code > in C++11, this falls
back to an implicit conversion on older compilers. This conversion refers
to the initialization state and not to the contained value. Using < code class = "computeroutput" >< span class = "identifier" > optional</ span >< span class = "special" > < </ span >< span class = "keyword" > bool</ span >< span class = "special" > > </ span ></ code >
can lead to subtle errors due to the implicit < code class = "computeroutput" >< span class = "keyword" > bool</ span ></ code >
conversion:
</ p >
< pre class = "programlisting" >< span class = "keyword" > void</ span > < span class = "identifier" > foo</ span > < span class = "special" > (</ span > < span class = "keyword" > bool</ span > < span class = "identifier" > v</ span > < span class = "special" > )</ span > < span class = "special" > ;</ span >
< span class = "keyword" > void</ span > < span class = "identifier" > bar</ span >< span class = "special" > ()</ span >
< span class = "special" > {</ span >
< span class = "identifier" > optional</ span >< span class = "special" > < </ span >< span class = "keyword" > bool</ span >< span class = "special" > > </ span > < span class = "identifier" > v</ span > < span class = "special" > =</ span > < span class = "keyword" > try</ span >< span class = "special" > ();</ span >
< span class = "comment" > // The following intended to pass the value of 'v' to foo():</ span >
< span class = "identifier" > foo</ span >< span class = "special" > (</ span >< span class = "identifier" > v</ span >< span class = "special" > );</ span >
< span class = "comment" > // But instead, the initialization state is passed</ span >
< span class = "comment" > // due to a typo: it should have been foo(*v).</ span >
< span class = "special" > }</ span >
</ pre >
< p >
The only implicit conversion is to < code class = "computeroutput" >< span class = "keyword" > bool</ span ></ code > ,
and it is safe in the sense that typical integral promotions don't apply
(i.e. if < code class = "computeroutput" >< span class = "identifier" > foo</ span >< span class = "special" > ()</ span ></ code >
takes an < code class = "computeroutput" >< span class = "keyword" > int</ span ></ code > instead, it won't
compile).
</ p >
< p >
Third, mixed comparisons with < code class = "computeroutput" >< span class = "keyword" > bool</ span ></ code >
work differently than similar mixed comparisons between pointers and < code class = "computeroutput" >< span class = "keyword" > bool</ span ></ code > , so the results might surprise you:
</ p >
< pre class = "programlisting" >< span class = "identifier" > optional</ span >< span class = "special" > < </ span >< span class = "keyword" > bool</ span >< span class = "special" > > </ span > < span class = "identifier" > oEmpty</ span >< span class = "special" > (</ span >< span class = "identifier" > none</ span >< span class = "special" > ),</ span > < span class = "identifier" > oTrue</ span >< span class = "special" > (</ span >< span class = "keyword" > true</ span >< span class = "special" > ),</ span > < span class = "identifier" > oFalse</ span >< span class = "special" > (</ span >< span class = "keyword" > false</ span >< span class = "special" > );</ span >
< span class = "keyword" > if</ span > < span class = "special" > (</ span >< span class = "identifier" > oEmpty</ span > < span class = "special" > ==</ span > < span class = "identifier" > none</ span >< span class = "special" > );</ span > < span class = "comment" > // renders true</ span >
< span class = "keyword" > if</ span > < span class = "special" > (</ span >< span class = "identifier" > oEmpty</ span > < span class = "special" > ==</ span > < span class = "keyword" > false</ span >< span class = "special" > );</ span > < span class = "comment" > // renders false!</ span >
< span class = "keyword" > if</ span > < span class = "special" > (</ span >< span class = "identifier" > oEmpty</ span > < span class = "special" > ==</ span > < span class = "keyword" > true</ span >< span class = "special" > );</ span > < span class = "comment" > // renders false!</ span >
< span class = "keyword" > if</ span > < span class = "special" > (</ span >< span class = "identifier" > oFalse</ span > < span class = "special" > ==</ span > < span class = "identifier" > none</ span >< span class = "special" > );</ span > < span class = "comment" > // renders false</ span >
< span class = "keyword" > if</ span > < span class = "special" > (</ span >< span class = "identifier" > oFalse</ span > < span class = "special" > ==</ span > < span class = "keyword" > false</ span >< span class = "special" > );</ span > < span class = "comment" > // renders true!</ span >
< span class = "keyword" > if</ span > < span class = "special" > (</ span >< span class = "identifier" > oFalse</ span > < span class = "special" > ==</ span > < span class = "keyword" > true</ span >< span class = "special" > );</ span > < span class = "comment" > // renders false</ span >
< span class = "keyword" > if</ span > < span class = "special" > (</ span >< span class = "identifier" > oTrue</ span > < span class = "special" > ==</ span > < span class = "identifier" > none</ span >< span class = "special" > );</ span > < span class = "comment" > // renders false</ span >
< span class = "keyword" > if</ span > < span class = "special" > (</ span >< span class = "identifier" > oTrue</ span > < span class = "special" > ==</ span > < span class = "keyword" > false</ span >< span class = "special" > );</ span > < span class = "comment" > // renders false</ span >
< span class = "keyword" > if</ span > < span class = "special" > (</ span >< span class = "identifier" > oTrue</ span > < span class = "special" > ==</ span > < span class = "keyword" > true</ span >< span class = "special" > );</ span > < span class = "comment" > // renders true</ span >
</ pre >
< p >
In other words, for < code class = "computeroutput" >< span class = "identifier" > optional</ span >< span class = "special" > <> </ span ></ code > , the following assertion does not
hold:
</ p >
< pre class = "programlisting" >< span class = "identifier" > assert</ span >< span class = "special" > ((</ span >< span class = "identifier" > opt</ span > < span class = "special" > ==</ span > < span class = "keyword" > false</ span >< span class = "special" > )</ span > < span class = "special" > ==</ span > < span class = "special" > (!</ span >< span class = "identifier" > opt</ span >< span class = "special" > ));</ span >
</ pre >
</ div >
</ div >
< table xmlns:rev = "http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width = "100%" >< tr >
< td align = "left" ></ td >
2021-03-10 23:07:18 +01:00
< td align = "right" >< div class = "copyright-footer" > Copyright © 2003-2007 Fernando Luis Cacciola Carballal< br > Copyright © 2014-2021 Andrzej Krzemieński< p >
2016-09-17 01:25:12 +02:00
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at < a href = "http://www.boost.org/LICENSE_1_0.txt" target = "_top" > http://www.boost.org/LICENSE_1_0.txt</ a > )
</ p >
</ div ></ td >
</ tr ></ table >
< hr >
< div class = "spirit-nav" >
< a accesskey = "p" href = "in_place_factories.html" >< img src = "../../../../../../doc/src/images/prev.png" alt = "Prev" ></ a >< a accesskey = "u" href = "../../optional/tutorial.html" >< img src = "../../../../../../doc/src/images/up.png" alt = "Up" ></ a >< a accesskey = "h" href = "../../index.html" >< img src = "../../../../../../doc/src/images/home.png" alt = "Home" ></ a >< a accesskey = "n" href = "gotchas/moved_from__optional_.html" >< img src = "../../../../../../doc/src/images/next.png" alt = "Next" ></ a >
</ div >
</ body >
</ html >