when_to_use_optional.html 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
  4. <title>When to use Optional</title>
  5. <link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
  6. <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
  7. <link rel="home" href="../../index.html" title="Boost.Optional">
  8. <link rel="up" href="../../optional/tutorial.html" title="Tutorial">
  9. <link rel="prev" href="design_overview/the_interface.html" title="The Interface">
  10. <link rel="next" href="relational_operators.html" title="Relational operators">
  11. </head>
  12. <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
  13. <table cellpadding="2" width="100%"><tr>
  14. <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
  15. <td align="center"><a href="../../../../../../index.html">Home</a></td>
  16. <td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
  17. <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
  18. <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
  19. <td align="center"><a href="../../../../../../more/index.htm">More</a></td>
  20. </tr></table>
  21. <hr>
  22. <div class="spirit-nav">
  23. <a accesskey="p" href="design_overview/the_interface.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="relational_operators.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
  24. </div>
  25. <div class="section">
  26. <div class="titlepage"><div><div><h3 class="title">
  27. <a name="boost_optional.tutorial.when_to_use_optional"></a><a class="link" href="when_to_use_optional.html" title="When to use Optional">When to
  28. use Optional</a>
  29. </h3></div></div></div>
  30. <p>
  31. It is recommended to use <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
  32. in situations where there is exactly one, clear (to all parties) reason for
  33. having no value of type <code class="computeroutput"><span class="identifier">T</span></code>,
  34. and where the lack of value is as natural as having any regular value of
  35. <code class="computeroutput"><span class="identifier">T</span></code>. One example of such situation
  36. is asking the user in some GUI form to optionally specify some limit on an
  37. <code class="computeroutput"><span class="keyword">int</span></code> value, but the user is allowed
  38. to say 'I want the number not to be constrained by the maximum'. For another
  39. example, consider a config parameter specifying how many threads the application
  40. should launch. Leaving this parameter unspecified means that the application
  41. should decide itself. For yet another example, consider a function returning
  42. the index of the smallest element in a <code class="computeroutput"><span class="identifier">vector</span></code>.
  43. We need to be prepared for the situation, where the <code class="computeroutput"><span class="identifier">vector</span></code>
  44. is empty. Therefore a natural signature for such function would be:
  45. </p>
  46. <pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
  47. <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">size_t</span><span class="special">&gt;</span> <span class="identifier">find_smallest_elem</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">vec</span><span class="special">);</span>
  48. </pre>
  49. <p>
  50. Here, having received an empty <code class="computeroutput"><span class="identifier">vec</span></code>
  51. and having no <code class="computeroutput"><span class="identifier">size_t</span></code> to return
  52. is not a <span class="emphasis"><em>failure</em></span> but a <span class="emphasis"><em>normal</em></span>,
  53. albeit irregular, situation.
  54. </p>
  55. <p>
  56. Another typical situation is to indicate that we do not have a value yet,
  57. but we expect to have it later. This notion can be used in implementing solutions
  58. like lazy initialization or a two-phase initialization.
  59. </p>
  60. <p>
  61. <code class="computeroutput"><span class="identifier">optional</span></code> can be used to take
  62. a non-<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html" target="_top"><code class="computeroutput"><span class="identifier">DefaultConstructible</span></code></a> type <code class="computeroutput"><span class="identifier">T</span></code> and create a sibling type with a default
  63. constructor. This is a way to add a <span class="emphasis"><em>null-state</em></span> to any
  64. type that doesn't have it already.
  65. </p>
  66. <p>
  67. Sometimes type <code class="computeroutput"><span class="identifier">T</span></code> already
  68. provides a built-in null-state, but it may still be useful to wrap it into
  69. <code class="computeroutput"><span class="identifier">optional</span></code>. Consider <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>.
  70. When you read a piece of text from a GUI form or a DB table, it is hardly
  71. ever that the empty string indicates anything else but a missing text. And
  72. some data bases do not even distinguish between a null string entry and a
  73. non-null string of length 0. Still, it may be practical to use <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span></code>
  74. to indicate in the returned type that we want to treat the empty string in
  75. a special dedicated program path:
  76. </p>
  77. <pre class="programlisting"><span class="keyword">if</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">name</span> <span class="special">=</span> <span class="identifier">ask_user_name</span><span class="special">())</span> <span class="special">{</span>
  78. <span class="identifier">assert</span><span class="special">(*</span><span class="identifier">name</span> <span class="special">!=</span> <span class="string">""</span><span class="special">);</span>
  79. <span class="identifier">logon_as</span><span class="special">(*</span><span class="identifier">name</span><span class="special">);</span>
  80. <span class="special">}</span>
  81. <span class="keyword">else</span> <span class="special">{</span>
  82. <span class="identifier">skip_logon</span><span class="special">();</span>
  83. <span class="special">}</span>
  84. </pre>
  85. <p>
  86. In the example above, the assertion indicates that if we choose to use this
  87. technique, we must translate the empty string state to an optional object
  88. with no contained value (inside function <code class="computeroutput"><span class="identifier">ask_user_name</span></code>).
  89. </p>
  90. <h5>
  91. <a name="boost_optional.tutorial.when_to_use_optional.h0"></a>
  92. <span class="phrase"><a name="boost_optional.tutorial.when_to_use_optional.not_recommended_usages"></a></span><a class="link" href="when_to_use_optional.html#boost_optional.tutorial.when_to_use_optional.not_recommended_usages">Not
  93. recommended usages</a>
  94. </h5>
  95. <p>
  96. It is not recommended to use <code class="computeroutput"><span class="identifier">optional</span></code>
  97. to indicate that we were not able to compute a value because of a <span class="emphasis"><em>failure</em></span>.
  98. It is difficult to define what a failure is, but it usually has one common
  99. characteristic: an associated information on the cause of the failure. This
  100. can be the type and member data of an exception object, or an error code.
  101. It is a bad design to signal a failure and not inform about the cause. If
  102. you do not want to use exceptions, and do not like the fact that by returning
  103. error codes you cannot return the computed value, you can use <a href="https://github.com/ptal/Boost.Expected" target="_top">Expected</a>
  104. library. It is sort of <a href="../../../../../variant/index.html" target="_top">Boost.Variant</a>
  105. that contains either a computed value or a reason why the computation failed.
  106. </p>
  107. <p>
  108. Sometimes the distinction into what is a failure and what is a valid but
  109. irregular result is blurry and depends on a particular usage and personal
  110. preference. Consider a function that converts a <code class="computeroutput"><span class="identifier">string</span></code>
  111. to an <code class="computeroutput"><span class="keyword">int</span></code>. Is it a failure that
  112. you cannot convert? It might in some cases, but in other you may call it
  113. exactly for the purpose of figuring out if a given <code class="computeroutput"><span class="identifier">string</span></code>
  114. is convertible, and you are not even interested in the resulting value. Sometimes
  115. when a conversion fails you may not consider it a failure, but you need to
  116. know why it cannot be converted; for instance at which character it is determined
  117. that the conversion is impossible. In this case returning <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
  118. will not suffice. Finally, there is a use case where an input string that
  119. does not represent an <code class="computeroutput"><span class="keyword">int</span></code> is
  120. not a failure condition, but during the conversion we use resources whose
  121. acquisition may fail. In that case the natural representation is to both
  122. return <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span></code> and
  123. signal failure:
  124. </p>
  125. <pre class="programlisting"><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">convert1</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">string</span><span class="special">&amp;</span> <span class="identifier">str</span><span class="special">);</span> <span class="comment">// throws</span>
  126. <span class="identifier">expected</span><span class="special">&lt;</span><span class="identifier">ErrorT</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;&gt;</span> <span class="identifier">convert2</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">string</span><span class="special">&amp;</span> <span class="identifier">str</span><span class="special">);</span> <span class="comment">// return either optional or error</span>
  127. </pre>
  128. </div>
  129. <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
  130. <td align="left"></td>
  131. <td align="right"><div class="copyright-footer">Copyright &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014-2018 Andrzej Krzemie&#324;ski<p>
  132. Distributed under the Boost Software License, Version 1.0. (See accompanying
  133. 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>)
  134. </p>
  135. </div></td>
  136. </tr></table>
  137. <hr>
  138. <div class="spirit-nav">
  139. <a accesskey="p" href="design_overview/the_interface.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="relational_operators.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
  140. </div>
  141. </body>
  142. </html>