• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Better Error Detection</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="Chapter 1. Boost.Convert 2.0">
8<link rel="up" href="../index.html" title="Chapter 1. Boost.Convert 2.0">
9<link rel="prev" href="getting_started/basic_conversion_failure_detection.html" title="Basic Conversion-Failure Detection">
10<link rel="next" href="default_converter.html" title="Default Converter">
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="getting_started/basic_conversion_failure_detection.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="default_converter.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
24</div>
25<div class="section">
26<div class="titlepage"><div><div><h2 class="title" style="clear: both">
27<a name="boost_convert.error_detection"></a><a class="link" href="error_detection.html" title="Better Error Detection">Better Error Detection</a>
28</h2></div></div></div>
29<div class="blockquote"><blockquote class="blockquote"><p>
30        <span class="bold"><strong><span class="emphasis"><em>"Detection is, or ought to be, an exact
31        science, ..." Sir Arthur Conan Doyle</em></span></strong></span>
32      </p></blockquote></div>
33<p>
34</p>
35<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">i2</span> <span class="special">=</span> <span class="identifier">convert</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="string">"not an int"</span><span class="special">,</span> <span class="identifier">cnv</span><span class="special">).</span><span class="identifier">value_or</span><span class="special">(-</span><span class="number">1</span><span class="special">);</span> <span class="comment">// after the call i2==-1</span>
36
37<span class="keyword">if</span> <span class="special">(</span><span class="identifier">i2</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">)</span> <span class="identifier">process_failure</span><span class="special">();</span>
38</pre>
39<p>
40    </p>
41<p>
42      The code above is straightforward and self-explanatory but, strictly speaking,
43      is not entirely correct as -1 might be the result of a conversion failure or
44      the successful conversion of the "-1" string. Still, in reality "spare"
45      values (outside the valid/sensible range) are often available to indicate conversion
46      failures. If so, such straightorward deployment might be adequate. Alternatively,
47      it might be not that uncommon to ignore conversion failures altogether and
48      to simply log the event and to proceed with the supplied fallback value.
49    </p>
50<p>
51      Applications outside these mentioned categories still require conversion failure
52      reliably detected and processed accordingly. The <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">lexical_cast</span></code>'s
53      (only) answer is to throw on failure and <span class="emphasis"><em>Boost.Convert</em></span>
54      supports that behavior as well:
55    </p>
56<p>
57</p>
58<pre class="programlisting"><span class="keyword">try</span>
59<span class="special">{</span>
60    <span class="keyword">int</span> <span class="identifier">i1</span> <span class="special">=</span> <span class="identifier">lexical_cast</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">str</span><span class="special">);</span>         <span class="comment">// Throws if the conversion fails.</span>
61    <span class="keyword">int</span> <span class="identifier">i2</span> <span class="special">=</span> <span class="identifier">convert</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">str</span><span class="special">,</span> <span class="identifier">cnv</span><span class="special">).</span><span class="identifier">value</span><span class="special">();</span> <span class="comment">// Throws if the conversion fails.</span>
62<span class="special">}</span>
63<span class="keyword">catch</span> <span class="special">(...)</span>
64<span class="special">{</span>
65    <span class="identifier">process_failure</span><span class="special">();</span>
66<span class="special">}</span>
67</pre>
68<p>
69    </p>
70<p>
71      However, to cater for a wider range of program-flow variations, <span class="emphasis"><em>Boost.Convert</em></span>
72      adds the flexibility of
73    </p>
74<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
75<li class="listitem">
76          delaying the moment when the conversion-failure exception is actually thrown
77          or
78        </li>
79<li class="listitem">
80          avoiding the exception altogether.
81        </li>
82</ul></div>
83<p>
84</p>
85<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">r1</span> <span class="special">=</span> <span class="identifier">convert</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">str1</span><span class="special">,</span> <span class="identifier">cnv</span><span class="special">);</span> <span class="comment">// Does not throw on conversion failure.</span>
86<span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">r2</span> <span class="special">=</span> <span class="identifier">convert</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">str2</span><span class="special">,</span> <span class="identifier">cnv</span><span class="special">);</span> <span class="comment">// Does not throw on conversion failure.</span>
87<span class="comment">// ...</span>
88<span class="keyword">try</span> <span class="comment">// Delayed processing of potential exceptions.</span>
89<span class="special">{</span>
90    <span class="keyword">int</span> <span class="identifier">i1</span> <span class="special">=</span> <span class="identifier">r1</span><span class="special">.</span><span class="identifier">value</span><span class="special">();</span> <span class="comment">// Will throw if conversion failed.</span>
91    <span class="keyword">int</span> <span class="identifier">i2</span> <span class="special">=</span> <span class="identifier">r2</span><span class="special">.</span><span class="identifier">value</span><span class="special">();</span> <span class="comment">// Will throw if conversion failed.</span>
92<span class="special">}</span>
93<span class="keyword">catch</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bad_optional_access</span> <span class="keyword">const</span><span class="special">&amp;)</span>
94<span class="special">{</span>
95    <span class="comment">// Handle failed conversion.</span>
96<span class="special">}</span>
97
98<span class="comment">// Exceptions are avoided altogether.</span>
99<span class="keyword">int</span> <span class="identifier">i1</span> <span class="special">=</span> <span class="identifier">r1</span> <span class="special">?</span> <span class="identifier">r1</span><span class="special">.</span><span class="identifier">value</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">fallback_value</span><span class="special">;</span>
100<span class="keyword">int</span> <span class="identifier">i2</span> <span class="special">=</span> <span class="identifier">r2</span><span class="special">.</span><span class="identifier">value_or</span><span class="special">(</span><span class="identifier">fallback_value</span><span class="special">);</span>
101<span class="keyword">int</span> <span class="identifier">i3</span> <span class="special">=</span> <span class="identifier">convert</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">str3</span><span class="special">,</span> <span class="identifier">cnv</span><span class="special">).</span><span class="identifier">value_or</span><span class="special">(</span><span class="identifier">fallback_value</span><span class="special">);</span>
102<span class="keyword">int</span> <span class="identifier">i4</span> <span class="special">=</span> <span class="identifier">convert</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">str3</span><span class="special">,</span> <span class="identifier">cnv</span><span class="special">).</span><span class="identifier">value_or_eval</span><span class="special">(</span><span class="identifier">fallback_function</span><span class="special">);</span>
103</pre>
104<p>
105    </p>
106<p>
107      Here <a href="../../../../../libs/optional/index.html" target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span></code></a>
108      steps forward as the actual type returned by <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">convert</span><span class="special">()</span></code> which until now we avoided by immediately
109      calling its value-accessor methods:
110    </p>
111<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">i1</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">convert</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">str1</span><span class="special">,</span> <span class="identifier">cnv</span><span class="special">).</span><span class="identifier">value</span><span class="special">();</span>
112<span class="keyword">int</span> <span class="identifier">i2</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">convert</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">str2</span><span class="special">,</span> <span class="identifier">cnv</span><span class="special">).</span><span class="identifier">value_or</span><span class="special">(</span><span class="identifier">fallback_value</span><span class="special">);</span>
113<span class="keyword">int</span> <span class="identifier">i3</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">convert</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">str3</span><span class="special">,</span> <span class="identifier">cnv</span><span class="special">).</span><span class="identifier">value_or_eval</span><span class="special">(</span><span class="identifier">fallback_function</span><span class="special">);</span>
114</pre>
115<div class="note"><table border="0" summary="Note">
116<tr>
117<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
118<th align="left">Note</th>
119</tr>
120<tr><td align="left" valign="top"><p>
121        One notable advantage of <code class="computeroutput"><span class="identifier">value_or_eval</span><span class="special">()</span></code> over <code class="computeroutput"><span class="identifier">value_or</span><span class="special">()</span></code> is that the actual calculation of the
122        <code class="computeroutput"><span class="identifier">fallback_value</span></code> is potentially
123        delayed and conditional on the success or failure of the conversion.
124      </p></td></tr>
125</table></div>
126<p>
127      From the user perspective, <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">lexical_cast</span></code>
128      processes failure in a somewhat one-dimensional non-negotiable manner. <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">convert</span></code>
129      takes a more flexible approach. It provides choice and leaves the decision
130      to the user. It is not unimaginable that, on the library level, propagating
131      the conversion-failure exception might be the only available option. On the
132      application level though, in my personal experience, the choice has overwhelmingly
133      been to handle conversion failures <span class="emphasis"><em>locally</em></span>, i.e. avoiding
134      conversion-failure exception propagation or, better still, avoiding exceptions
135      altogether with program flows similar to:
136    </p>
137<p>
138</p>
139<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">res</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">convert</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">str</span><span class="special">,</span> <span class="identifier">cnv</span><span class="special">);</span>
140
141<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">res</span><span class="special">)</span> <span class="identifier">log</span><span class="special">(</span><span class="string">"str conversion failed!"</span><span class="special">);</span>
142
143<span class="keyword">int</span> <span class="identifier">i1</span> <span class="special">=</span> <span class="identifier">res</span><span class="special">.</span><span class="identifier">value_or</span><span class="special">(</span><span class="identifier">fallback_value</span><span class="special">);</span>
144
145<span class="comment">// ...proceed</span>
146</pre>
147<p>
148    </p>
149<p>
150      and
151    </p>
152<p>
153</p>
154<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">fallback_func</span>
155<span class="special">{</span>
156    <span class="keyword">int</span> <span class="keyword">operator</span><span class="special">()()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="identifier">log</span><span class="special">(</span><span class="string">"Failed to convert"</span><span class="special">);</span> <span class="keyword">return</span> <span class="number">42</span><span class="special">;</span> <span class="special">}</span>
157<span class="special">};</span>
158</pre>
159<p>
160    </p>
161<p>
162</p>
163<pre class="programlisting"><span class="comment">// Fallback function is called when failed</span>
164<span class="keyword">int</span> <span class="identifier">i2</span> <span class="special">=</span> <span class="identifier">convert</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">str</span><span class="special">,</span> <span class="identifier">cnv</span><span class="special">).</span><span class="identifier">value_or_eval</span><span class="special">(</span><span class="identifier">fallback_func</span><span class="special">());</span>
165<span class="keyword">int</span> <span class="identifier">i3</span> <span class="special">=</span> <span class="identifier">convert</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;(</span><span class="identifier">str</span><span class="special">,</span> <span class="identifier">cnv</span><span class="special">,</span> <span class="identifier">fallback_func</span><span class="special">());</span> <span class="comment">// Same as above. Alternative API.</span>
166</pre>
167<p>
168    </p>
169</div>
170<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
171<td align="left"></td>
172<td align="right"><div class="copyright-footer">Copyright © 2009-2016 Vladimir Batov<p>
173        Distributed under the Boost Software License, Version 1.0. See copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>.
174      </p>
175</div></td>
176</tr></table>
177<hr>
178<div class="spirit-nav">
179<a accesskey="p" href="getting_started/basic_conversion_failure_detection.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="default_converter.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
180</div>
181</body>
182</html>
183