Improved documentation. Added some noexcept.

This commit is contained in:
Andrzej Krzemienski
2014-05-07 17:07:12 +02:00
parent 6a790e0c97
commit f94846ccc5
17 changed files with 405 additions and 329 deletions

View File

@ -6,7 +6,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<link rel="prev" href="implementation_notes.html" title="Implementation Notes">
<link rel="prev" href="type_requirements.html" title="Type requirements">
<link rel="next" href="acknowledgments.html" title="Acknowledgments">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
@ -20,7 +20,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="implementation_notes.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="acknowledgments.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
<a accesskey="p" href="type_requirements.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="acknowledgments.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
@ -42,7 +42,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="implementation_notes.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="acknowledgments.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
<a accesskey="p" href="type_requirements.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="acknowledgments.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -629,6 +629,22 @@
</pre>
</li>
</ul></div>
<p>
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p>
<a name="reference_optional_operator_equal_none_t"></a><div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&amp;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">none_t</span> <span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span></code>
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<span class="bold"><strong>Effect:</strong></span> If <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is initialized destroys its contained
value.
</li>
<li class="listitem">
<span class="bold"><strong>Postconditions: </strong></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is uninitialized.
</li>
</ul></div>
<p>
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p>
@ -1122,7 +1138,7 @@
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
</p>
<a name="reference_optional_reset"></a><div class="blockquote"><blockquote class="blockquote"><p>
<code class="computeroutput"><span class="keyword">void</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">reset</span><span class="special">()</span> <span class="special">;</span></code>
<code class="computeroutput"><span class="keyword">void</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">reset</span><span class="special">()</span> <span class="keyword">noexcept</span> <span class="special">;</span></code>
</p></blockquote></div>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
<span class="bold"><strong>Deprecated:</strong></span> Same as <code class="computeroutput"><span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">detail</span><span class="special">::</span><span class="identifier">none_t</span> <span class="special">);</span></code>

View File

@ -6,7 +6,7 @@
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<link rel="prev" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<link rel="prev" href="motivation.html" title="Motivation">
<link rel="next" href="synopsis.html" title="Synopsis">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
@ -20,7 +20,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../index.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="synopsis.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
<a accesskey="p" href="motivation.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="synopsis.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
@ -407,7 +407,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../index.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="synopsis.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
<a accesskey="p" href="motivation.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="synopsis.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -28,8 +28,36 @@
Guarantees</a>
</h2></div></div></div>
<p>
Because of the current implementation (see <a class="link" href="implementation_notes.html" title="Implementation Notes">Implementation
Notes</a>), all of the assignment methods:
This library assumes that <code class="computeroutput"><span class="identifier">T</span></code>'s
destructor does not throw exceptions. If it does, the behaviour of many operations
on <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> is
undefined.
</p>
<p>
The following mutating operations never throw exceptions:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">none_t</span> <span class="special">)</span> <span class="keyword">noexcept</span></code>
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">reset</span><span class="special">()</span> <span class="keyword">noexcept</span></code>
</li>
</ul></div>
<p>
In addition, the following constructors and the destructor never throw exceptions:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">optional</span><span class="special">()</span>
<span class="keyword">noexcept</span></code>
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">optional</span><span class="special">(</span> <span class="identifier">none_t</span> <span class="special">)</span> <span class="keyword">noexcept</span></code>
</li>
</ul></div>
<p>
Regarding the following assignment functions:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
@ -52,88 +80,71 @@
<span class="special">)</span> </code>
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">reset</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;)</span></code>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">reset</span><span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">)</span></code>
</li>
</ul></div>
<p>
Can only <span class="emphasis"><em>guarantee</em></span> the <span class="underline">basic
exception safety</span>: The lvalue optional is left <span class="underline">uninitialized</span>
if an exception is thrown (any previous value is <span class="emphasis"><em>first</em></span>
destroyed using <code class="computeroutput"><span class="identifier">T</span><span class="special">::~</span><span class="identifier">T</span><span class="special">()</span></code>)
They forward calls to the corresponding <code class="computeroutput"><span class="identifier">T</span></code>'s
constructors or assignments (depending on whether the optional object is initialized
or not); so if both <code class="computeroutput"><span class="identifier">T</span></code>'s constructor
and the assignment provide strong exception safety guarantee, <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>'s assignment
also provides strong exception safety guarantee; otherwise we only get the
basic guarantee. Additionally, if both involved <code class="computeroutput"><span class="identifier">T</span></code>'s
constructor and the assignment never throw, <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>'s
assignment also never throws.
</p>
<p>
On the other hand, the <span class="emphasis"><em>uninitializing</em></span> methods:
Unless <code class="computeroutput"><span class="identifier">T</span></code>'s constructor or assignment
throws, <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> does
not throw anything else on its own. A throw during assignment never changes
the initialization state of any optional object involved:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">detail</span><span class="special">::</span><span class="identifier">none_t</span> <span class="special">)</span></code>
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">reset</span><span class="special">()</span></code>
</li>
</ul></div>
<p>
Provide the no-throw guarantee (assuming a no-throw <code class="computeroutput"><span class="identifier">T</span><span class="special">::~</span><span class="identifier">T</span><span class="special">()</span></code>)
</p>
<p>
However, since <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;&gt;</span></code>
itself doesn't throw any exceptions, the only source for exceptions here are
<code class="computeroutput"><span class="identifier">T</span></code>'s constructor, so if you
know the exception guarantees for <code class="computeroutput"><span class="identifier">T</span><span class="special">::</span><span class="identifier">T</span> <span class="special">(</span>
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">)</span></code>, you
know that <code class="computeroutput"><span class="identifier">optional</span></code>'s assignment
and reset has the same guarantees.
</p>
<pre class="programlisting"><span class="comment">//</span>
<span class="comment">// Case 1: Exception thrown during assignment.</span>
<span class="comment">//</span>
<span class="identifier">T</span> <span class="identifier">v0</span><span class="special">(</span><span class="number">123</span><span class="special">);</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">opt0</span><span class="special">(</span><span class="identifier">v0</span><span class="special">);</span>
<pre class="programlisting"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">opt1</span><span class="special">(</span><span class="identifier">val1</span><span class="special">);</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">opt2</span><span class="special">(</span><span class="identifier">val2</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">opt1</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">opt2</span><span class="special">);</span>
<span class="keyword">try</span>
<span class="special">{</span>
<span class="identifier">T</span> <span class="identifier">v1</span><span class="special">(</span><span class="number">456</span><span class="special">);</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">opt1</span><span class="special">(</span><span class="identifier">v1</span><span class="special">);</span>
<span class="identifier">opt0</span> <span class="special">=</span> <span class="identifier">opt1</span> <span class="special">;</span>
<span class="comment">// If no exception was thrown, assignment succeeded.</span>
<span class="identifier">assert</span><span class="special">(</span> <span class="special">*</span><span class="identifier">opt0</span> <span class="special">==</span> <span class="identifier">v1</span> <span class="special">)</span> <span class="special">;</span>
<span class="identifier">opt1</span> <span class="special">=</span> <span class="identifier">opt2</span><span class="special">;</span> <span class="comment">// throws</span>
<span class="special">}</span>
<span class="keyword">catch</span><span class="special">(...)</span>
<span class="special">{</span>
<span class="comment">// If any exception was thrown, 'opt0' is reset to uninitialized.</span>
<span class="identifier">assert</span><span class="special">(</span> <span class="special">!</span><span class="identifier">opt0</span> <span class="special">)</span> <span class="special">;</span>
<span class="special">}</span>
<span class="comment">//</span>
<span class="comment">// Case 2: Exception thrown during reset(v)</span>
<span class="comment">//</span>
<span class="identifier">T</span> <span class="identifier">v0</span><span class="special">(</span><span class="number">123</span><span class="special">);</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">opt</span><span class="special">(</span><span class="identifier">v0</span><span class="special">);</span>
<span class="keyword">try</span>
<span class="special">{</span>
<span class="identifier">T</span> <span class="identifier">v1</span><span class="special">(</span><span class="number">456</span><span class="special">);</span>
<span class="identifier">opt</span><span class="special">.</span><span class="identifier">reset</span> <span class="special">(</span> <span class="identifier">v1</span> <span class="special">)</span> <span class="special">;</span>
<span class="comment">// If no exception was thrown, reset succeeded.</span>
<span class="identifier">assert</span><span class="special">(</span> <span class="special">*</span><span class="identifier">opt</span> <span class="special">==</span> <span class="identifier">v1</span> <span class="special">)</span> <span class="special">;</span>
<span class="special">}</span>
<span class="keyword">catch</span><span class="special">(...)</span>
<span class="special">{</span>
<span class="comment">// If any exception was thrown, 'opt' is reset to uninitialized.</span>
<span class="identifier">assert</span><span class="special">(</span> <span class="special">!</span><span class="identifier">opt</span> <span class="special">)</span> <span class="special">;</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">opt1</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">opt2</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
This also applies to move assignments/constructors. However, move operations
are made no-throw more often.
</p>
<h4>
<a name="boost_optional.exception_safety_guarantees.h0"></a>
<span class="phrase"><a name="boost_optional.exception_safety_guarantees.swap"></a></span><a class="link" href="exception_safety_guarantees.html#boost_optional.exception_safety_guarantees.swap">Swap</a>
</h4>
<p>
<code class="computeroutput"><span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;,</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="special">)</span></code> has the same exception guarantee as <code class="computeroutput"><span class="identifier">swap</span><span class="special">(</span><span class="identifier">T</span><span class="special">&amp;,</span><span class="identifier">T</span><span class="special">&amp;)</span></code>
when both optionals are initialized. If only one of the optionals is initialized,
it gives the same <span class="emphasis"><em>basic</em></span> exception guarantee as <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">reset</span><span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">)</span></code> (since
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">reset</span><span class="special">()</span></code> doesn't throw). If none of the optionals
is initialized, it has no-throw guarantee since it is a no-op.
Unless <code class="computeroutput"><span class="identifier">swap</span></code> on optional is
customized, its primary implementation forwards calls to <code class="computeroutput"><span class="identifier">T</span></code>'s
<code class="computeroutput"><span class="identifier">swap</span></code> or move constructor (depending
on the initialization state of the optional objects). Thus, if both <code class="computeroutput"><span class="identifier">T</span></code>'s <code class="computeroutput"><span class="identifier">swap</span></code>
and move constructor never throw, <code class="computeroutput"><span class="identifier">swap</span></code>
on <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> never
throws. similarly, if both <code class="computeroutput"><span class="identifier">T</span></code>'s
<code class="computeroutput"><span class="identifier">swap</span></code> and move constructor offer
strong guarantee, <code class="computeroutput"><span class="identifier">swap</span></code> on
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> also
offers a strong guarantee.
</p>
<p>
In case <code class="computeroutput"><span class="identifier">swap</span></code> on optional is
customized, the call to <code class="computeroutput"><span class="identifier">T</span></code>'s
move constructor are replaced with the calls to <code class="computeroutput"><span class="identifier">T</span></code>'s
default constructor followed by <code class="computeroutput"><span class="identifier">swap</span></code>.
(This is more useful on older compilers that do not support move semantics,
when one wants to acheive stronger exception safety guarantees.) In this case
the exception safety guarantees for <code class="computeroutput"><span class="identifier">swap</span></code>
are reliant on the guarantees of <code class="computeroutput"><span class="identifier">T</span></code>'s
<code class="computeroutput"><span class="identifier">swap</span></code> and default constructor
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>

View File

@ -31,12 +31,12 @@
currently implemented using a custom aligned storage facility built from <code class="computeroutput"><span class="identifier">alignment_of</span></code> and <code class="computeroutput"><span class="identifier">type_with_alignment</span></code>
(both from Type Traits). It uses a separate boolean flag to indicate the initialization
state. Placement new with <code class="computeroutput"><span class="identifier">T</span></code>'s
copy constructor and <code class="computeroutput"><span class="identifier">T</span></code>'s destructor
are explicitly used to initialize,copy and destroy optional values. As a result,
<code class="computeroutput"><span class="identifier">T</span></code>'s default constructor is
effectively by-passed, but the exception guarantees are basic. It is planned
to replace the current implementation with another with stronger exception
safety, such as a future <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">variant</span></code>.
copy/move constructor and <code class="computeroutput"><span class="identifier">T</span></code>'s
destructor are explicitly used to initialize, copy, move and destroy optional
values. As a result, <code class="computeroutput"><span class="identifier">T</span></code>'s default
constructor is effectively by-passed, but the exception guarantees are basic.
It is planned to replace the current implementation with another with stronger
exception safety, such as a future <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">variant</span></code>.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>

View File

@ -0,0 +1,128 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Motivation</title>
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<link rel="prev" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<link rel="next" href="development.html" title="Development">
</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="../index.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="development.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_optional.motivation"></a><a class="link" href="motivation.html" title="Motivation">Motivation</a>
</h2></div></div></div>
<p>
Consider these functions which should return a value but which might not have
a value to return:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
(A) <code class="computeroutput"><span class="keyword">double</span> <span class="identifier">sqrt</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">n</span> <span class="special">);</span></code>
</li>
<li class="listitem">
(B) <code class="computeroutput"><span class="keyword">char</span> <span class="identifier">get_async_input</span><span class="special">();</span></code>
</li>
<li class="listitem">
(C) <code class="computeroutput"><span class="identifier">point</span> <span class="identifier">polygon</span><span class="special">::</span><span class="identifier">get_any_point_effectively_inside</span><span class="special">();</span></code>
</li>
</ul></div>
<p>
There are different approaches to the issue of not having a value to return.
</p>
<p>
A typical approach is to consider the existence of a valid return value as
a postcondition, so that if the function cannot compute the value to return,
it has either undefined behavior (and can use assert in a debug build) or uses
a runtime check and throws an exception if the postcondition is violated. This
is a reasonable choice for example, for function (A), because the lack of a
proper return value is directly related to an invalid parameter (out of domain
argument), so it is appropriate to require the callee to supply only parameters
in a valid domain for execution to continue normally.
</p>
<p>
However, function (B), because of its asynchronous nature, does not fail just
because it can't find a value to return; so it is incorrect to consider such
a situation an error and assert or throw an exception. This function must return,
and somehow, must tell the callee that it is not returning a meaningful value.
</p>
<p>
A similar situation occurs with function (C): it is conceptually an error to
ask a <span class="emphasis"><em>null-area</em></span> polygon to return a point inside itself,
but in many applications, it is just impractical for performance reasons to
treat this as an error (because detecting that the polygon has no area might
be too expensive to be required to be tested previously), and either an arbitrary
point (typically at infinity) is returned, or some efficient way to tell the
callee that there is no such point is used.
</p>
<p>
There are various mechanisms to let functions communicate that the returned
value is not valid. One such mechanism, which is quite common since it has
zero or negligible overhead, is to use a special value which is reserved to
communicate this. Classical examples of such special values are <code class="computeroutput"><span class="identifier">EOF</span></code>, <code class="computeroutput"><span class="identifier">string</span><span class="special">::</span><span class="identifier">npos</span></code>, points
at infinity, etc...
</p>
<p>
When those values exist, i.e. the return type can hold all meaningful values
<span class="emphasis"><em>plus</em></span> the <span class="emphasis"><em>signal</em></span> value, this mechanism
is quite appropriate and well known. Unfortunately, there are cases when such
values do not exist. In these cases, the usual alternative is either to use
a wider type, such as <code class="computeroutput"><span class="keyword">int</span></code> in place
of <code class="computeroutput"><span class="keyword">char</span></code>; or a compound type, such
as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</span></code>.
</p>
<p>
Returning a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</span></code>, thus attaching a boolean flag to the result
which indicates if the result is meaningful, has the advantage that can be
turned into a consistent idiom since the first element of the pair can be whatever
the function would conceptually return. For example, the last two functions
could have the following interface:
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</span> <span class="identifier">get_async_input</span><span class="special">();</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</span> <span class="identifier">polygon</span><span class="special">::</span><span class="identifier">get_any_point_effectively_inside</span><span class="special">();</span>
</pre>
<p>
These functions use a consistent interface for dealing with possibly nonexistent
results:
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</span> <span class="identifier">p</span> <span class="special">=</span> <span class="identifier">poly</span><span class="special">.</span><span class="identifier">get_any_point_effectively_inside</span><span class="special">();</span>
<span class="keyword">if</span> <span class="special">(</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">second</span> <span class="special">)</span>
<span class="identifier">flood_fill</span><span class="special">(</span><span class="identifier">p</span><span class="special">.</span><span class="identifier">first</span><span class="special">);</span>
</pre>
<p>
However, not only is this quite a burden syntactically, it is also error prone
since the user can easily use the function result (first element of the pair)
without ever checking if it has a valid value.
</p>
<p>
Clearly, we need a better idiom.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;ski<p>
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="../index.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="development.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -60,7 +60,7 @@
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Copies of <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;</span></code>
will copy the references but all these references will nonetheless reefer
will copy the references but all these references will nonetheless refer
to the same object.
</li>
<li class="listitem">
@ -68,6 +68,21 @@
than the reference itself.
</li>
</ul></div>
<div class="warning"><table border="0" summary="Warning">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../doc/src/images/warning.png"></td>
<th align="left">Warning</th>
</tr>
<tr><td align="left" valign="top"><p>
On compilers that do not conform to Standard C++ rules of reference binding,
operations on optional references might give adverse results: rather than
binding a reference to a designated object they may create a temporary and
bind to it. Compilers known to have these deficiencies include GCC versions
4.2, 4.3, 4.4, 4.5; QCC 4.4.2; MSVC versions 8.0, 9.0, 10.0, 11.0, 12.0.
On these compilers prefer using direct-initialization and copy assignment
of optional references to copy-initialization and assignment from <code class="computeroutput"><span class="identifier">T</span><span class="special">&amp;</span></code>.
</p></td></tr>
</table></div>
<h4>
<a name="boost_optional.optional_references.h0"></a>
<span class="phrase"><a name="boost_optional.optional_references.rvalue_references"></a></span><a class="link" href="optional_references.html#boost_optional.optional_references.rvalue_references">Rvalue

View File

@ -60,7 +60,7 @@
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">TypedInPlaceFactory</span><span class="special">&gt;</span> <span class="keyword">explicit</span> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">TypedInPlaceFactory</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_factory"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">none_t</span> <span class="special">)</span> <span class="special">;</span>
<span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">none_t</span> <span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_equal_none_t"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_equal_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
@ -100,7 +100,7 @@
<span class="comment">// deprecated methods</span>
<span class="comment">// (deprecated)</span>
<span class="keyword">void</span> <span class="identifier">reset</span><span class="special">()</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_reset"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="keyword">void</span> <span class="identifier">reset</span><span class="special">()</span> <span class="keyword">noexcept</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_reset"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="comment">// (deprecated)</span>
<span class="keyword">void</span> <span class="identifier">reset</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_reset_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>

View File

@ -7,7 +7,7 @@
<link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<link rel="prev" href="exception_safety_guarantees.html" title="Exception Safety Guarantees">
<link rel="next" href="implementation_notes.html" title="Implementation Notes">
<link rel="next" href="dependencies_and_portability.html" title="Dependencies and Portability">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
@ -20,7 +20,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="exception_safety_guarantees.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="implementation_notes.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
<a accesskey="p" href="exception_safety_guarantees.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="dependencies_and_portability.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
@ -47,7 +47,7 @@
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="exception_safety_guarantees.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="implementation_notes.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
<a accesskey="p" href="exception_safety_guarantees.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="dependencies_and_portability.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>