alternatives.html 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
  4. <title>Annex: Alternatives</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&#160;1.&#160;Boost.ScopeExit 1.1.0">
  8. <link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">
  9. <link rel="prev" href="tutorial.html" title="Tutorial">
  10. <link rel="next" href="no_variadic_macros.html" title="Annex: No Variadic Macros">
  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="tutorial.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="no_variadic_macros.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="scope_exit.alternatives"></a><a class="link" href="alternatives.html" title="Annex: Alternatives">Annex: Alternatives</a>
  28. </h2></div></div></div>
  29. <p>
  30. This section presents some alternative and related work to <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a>.
  31. </p>
  32. <h4>
  33. <a name="scope_exit.alternatives.h0"></a>
  34. <span class="phrase"><a name="scope_exit.alternatives.try_catch"></a></span><a class="link" href="alternatives.html#scope_exit.alternatives.try_catch">Try-Catch</a>
  35. </h4>
  36. <p>
  37. This is an example of using a badly designed <code class="computeroutput"><span class="identifier">file</span></code>
  38. class. An instance of <code class="computeroutput"><span class="identifier">file</span></code>
  39. does not close the file in its destructor, a programmer is expected to call
  40. the <code class="computeroutput"><span class="identifier">close</span></code> member function explicitly.
  41. For example (see also <a href="../../../example/try_catch.cpp" target="_top"><code class="literal">try_catch.cpp</code></a>):
  42. </p>
  43. <p>
  44. </p>
  45. <pre class="programlisting"><span class="identifier">file</span> <span class="identifier">passwd</span><span class="special">;</span>
  46. <span class="keyword">try</span> <span class="special">{</span>
  47. <span class="identifier">passwd</span><span class="special">.</span><span class="identifier">open</span><span class="special">(</span><span class="string">"/etc/passwd"</span><span class="special">);</span>
  48. <span class="comment">// ...</span>
  49. <span class="identifier">passwd</span><span class="special">.</span><span class="identifier">close</span><span class="special">();</span>
  50. <span class="special">}</span> <span class="keyword">catch</span><span class="special">(...)</span> <span class="special">{</span>
  51. <span class="identifier">std</span><span class="special">::</span><span class="identifier">clog</span> <span class="special">&lt;&lt;</span> <span class="string">"could not get user info"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
  52. <span class="keyword">if</span><span class="special">(</span><span class="identifier">passwd</span><span class="special">.</span><span class="identifier">is_open</span><span class="special">())</span> <span class="identifier">passwd</span><span class="special">.</span><span class="identifier">close</span><span class="special">();</span>
  53. <span class="keyword">throw</span><span class="special">;</span>
  54. <span class="special">}</span>
  55. </pre>
  56. <p>
  57. </p>
  58. <p>
  59. Note the following issues with this approach:
  60. </p>
  61. <div class="orderedlist"><ol class="orderedlist" type="1">
  62. <li class="listitem">
  63. The <code class="computeroutput"><span class="identifier">passwd</span></code> object is defined
  64. outside of the <code class="computeroutput"><span class="keyword">try</span></code> block because
  65. this object is required inside the <code class="computeroutput"><span class="keyword">catch</span></code>
  66. block to close the file.
  67. </li>
  68. <li class="listitem">
  69. The <code class="computeroutput"><span class="identifier">passwd</span></code> object is not
  70. fully constructed until after the <code class="computeroutput"><span class="identifier">open</span></code>
  71. member function returns.
  72. </li>
  73. <li class="listitem">
  74. If opening throws, the <code class="computeroutput"><span class="identifier">passwd</span><span class="special">.</span><span class="identifier">close</span><span class="special">()</span></code> should not be called, hence the call
  75. to <code class="computeroutput"><span class="identifier">passwd</span><span class="special">.</span><span class="identifier">is_open</span><span class="special">()</span></code>.
  76. </li>
  77. </ol></div>
  78. <p>
  79. The <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a> approach does not have
  80. any of these issues. For example (see also <a href="../../../example/try_catch.cpp" target="_top"><code class="literal">try_catch.cpp</code></a>):
  81. </p>
  82. <p>
  83. </p>
  84. <pre class="programlisting"><span class="keyword">try</span> <span class="special">{</span>
  85. <span class="identifier">file</span> <span class="identifier">passwd</span><span class="special">(</span><span class="string">"/etc/passwd"</span><span class="special">);</span>
  86. <span class="identifier">BOOST_SCOPE_EXIT</span><span class="special">(&amp;</span><span class="identifier">passwd</span><span class="special">)</span> <span class="special">{</span>
  87. <span class="identifier">passwd</span><span class="special">.</span><span class="identifier">close</span><span class="special">();</span>
  88. <span class="special">}</span> <span class="identifier">BOOST_SCOPE_EXIT_END</span>
  89. <span class="special">}</span> <span class="keyword">catch</span><span class="special">(...)</span> <span class="special">{</span>
  90. <span class="identifier">std</span><span class="special">::</span><span class="identifier">clog</span> <span class="special">&lt;&lt;</span> <span class="string">"could not get user info"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
  91. <span class="keyword">throw</span><span class="special">;</span>
  92. <span class="special">}</span>
  93. </pre>
  94. <p>
  95. </p>
  96. <h4>
  97. <a name="scope_exit.alternatives.h1"></a>
  98. <span class="phrase"><a name="scope_exit.alternatives.raii"></a></span><a class="link" href="alternatives.html#scope_exit.alternatives.raii">RAII</a>
  99. </h4>
  100. <p>
  101. <a href="http://www.research.att.com/~bs/glossary.html#Gresource-acquisition-is-initialization" target="_top">RAII</a>
  102. is absolutely perfect for the <code class="computeroutput"><span class="identifier">file</span></code>
  103. class introduced above. Use of a properly designed <code class="computeroutput"><span class="identifier">file</span></code>
  104. class would look like:
  105. </p>
  106. <pre class="programlisting"><span class="keyword">try</span> <span class="special">{</span>
  107. <span class="identifier">file</span> <span class="identifier">passwd</span><span class="special">(</span><span class="string">"/etc/passwd"</span><span class="special">);</span>
  108. <span class="comment">// ...</span>
  109. <span class="special">}</span> <span class="keyword">catch</span><span class="special">(...)</span> <span class="special">{</span>
  110. <span class="identifier">std</span><span class="special">::</span><span class="identifier">clog</span> <span class="special">&lt;&lt;</span> <span class="string">"could not get user info"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
  111. <span class="keyword">throw</span><span class="special">;</span>
  112. <span class="special">}</span>
  113. </pre>
  114. <p>
  115. However, using <a href="http://www.research.att.com/~bs/glossary.html#Gresource-acquisition-is-initialization" target="_top">RAII</a>
  116. to build up a <a href="http://www.research.att.com/~bs/glossary.html#Gstrong-guarantee" target="_top">strong
  117. guarantee</a> could introduce a lot of non-reusable <a href="http://www.research.att.com/~bs/glossary.html#Gresource-acquisition-is-initialization" target="_top">RAII</a>
  118. types. For example:
  119. </p>
  120. <pre class="programlisting"><span class="identifier">persons_</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">a_person</span><span class="special">);</span>
  121. <span class="identifier">pop_back_if_not_commit</span> <span class="identifier">pop_back_if_not_commit_guard</span><span class="special">(</span><span class="identifier">commit</span><span class="special">,</span> <span class="identifier">persons_</span><span class="special">);</span>
  122. </pre>
  123. <p>
  124. The <code class="computeroutput"><span class="identifier">pop_back_if_not_commit</span></code>
  125. class is either defined out of the scope or as a local class:
  126. </p>
  127. <pre class="programlisting"><span class="keyword">class</span> <span class="identifier">pop_back_if_not_commit</span> <span class="special">{</span>
  128. <span class="keyword">bool</span> <span class="identifier">commit_</span><span class="special">;</span>
  129. <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">person</span><span class="special">&gt;&amp;</span> <span class="identifier">vec_</span><span class="special">;</span>
  130. <span class="comment">// ...</span>
  131. <span class="special">~</span><span class="identifier">pop_back_if_not_commit</span><span class="special">()</span> <span class="special">{</span>
  132. <span class="keyword">if</span><span class="special">(!</span><span class="identifier">commit_</span><span class="special">)</span> <span class="identifier">vec_</span><span class="special">.</span><span class="identifier">pop_back</span><span class="special">();</span>
  133. <span class="special">}</span>
  134. <span class="special">};</span>
  135. </pre>
  136. <p>
  137. In some cases <a href="http://www.research.att.com/~bs/glossary.html#Gstrong-guarantee" target="_top">strong
  138. guarantee</a> can be accomplished with standard utilities:
  139. </p>
  140. <pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">auto_ptr</span><span class="special">&lt;</span><span class="identifier">Person</span><span class="special">&gt;</span> <span class="identifier">superman_ptr</span><span class="special">(</span><span class="keyword">new</span> <span class="identifier">superman</span><span class="special">());</span>
  141. <span class="identifier">persons_</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">superman_ptr</span><span class="special">.</span><span class="identifier">get</span><span class="special">());</span>
  142. <span class="identifier">superman_ptr</span><span class="special">.</span><span class="identifier">release</span><span class="special">();</span> <span class="comment">// persons_ successfully took ownership</span>
  143. </pre>
  144. <p>
  145. Or with specialized containers such as <a href="http://www.boost.org/libs/ptr_container" target="_top">Boost.PointerContainer</a>
  146. or <a href="http://www.boost.org/libs/multi_index" target="_top">Boost.Multi-Index</a>.
  147. </p>
  148. <h4>
  149. <a name="scope_exit.alternatives.h2"></a>
  150. <span class="phrase"><a name="scope_exit.alternatives.scope_guards"></a></span><a class="link" href="alternatives.html#scope_exit.alternatives.scope_guards">Scope
  151. Guards</a>
  152. </h4>
  153. <p>
  154. Imagine that a new currency rate is introduced before performing a transaction
  155. (see also []):
  156. </p>
  157. <p>
  158. </p>
  159. <pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">commit</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
  160. <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">currency</span><span class="special">(</span><span class="string">"EUR"</span><span class="special">);</span>
  161. <span class="keyword">double</span> <span class="identifier">rate</span> <span class="special">=</span> <span class="number">1.3326</span><span class="special">;</span>
  162. <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;</span> <span class="identifier">rates</span><span class="special">;</span>
  163. <span class="keyword">bool</span> <span class="identifier">currency_rate_inserted</span> <span class="special">=</span>
  164. <span class="identifier">rates</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">make_pair</span><span class="special">(</span><span class="identifier">currency</span><span class="special">,</span> <span class="identifier">rate</span><span class="special">)).</span><span class="identifier">second</span><span class="special">;</span>
  165. <span class="comment">// Transaction...</span>
  166. </pre>
  167. <p>
  168. </p>
  169. <p>
  170. If the transaction does not complete, the currency must be erased from <code class="computeroutput"><span class="identifier">rates</span></code>. This can be done with <a href="http://www.ddj.com/dept/cpp/184403758" target="_top">ScopeGuard</a>
  171. and <a href="http://www.boost.org/libs/lambda" target="_top">Boost.Lambda</a> (or
  172. <a href="http://www.boost.org/libs/phoenix" target="_top">Boost.Phoenix</a>):
  173. </p>
  174. <pre class="programlisting"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">lambda</span><span class="special">;</span>
  175. <span class="identifier">ON_BLOCK_EXIT</span><span class="special">(</span>
  176. <span class="identifier">if_</span><span class="special">(</span><span class="identifier">currency_rate_inserted</span> <span class="special">&amp;&amp;</span> <span class="special">!</span><span class="identifier">_1</span><span class="special">)</span> <span class="special">[</span>
  177. <span class="identifier">bind</span><span class="special">(</span>
  178. <span class="keyword">static_cast</span><span class="special">&lt;</span>
  179. <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">size_type</span>
  180. <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;::*)(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;)</span>
  181. <span class="special">&gt;(&amp;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">&gt;::</span><span class="identifier">erase</span><span class="special">)</span>
  182. <span class="special">,</span> <span class="special">&amp;</span><span class="identifier">rates</span>
  183. <span class="special">,</span> <span class="identifier">currency</span>
  184. <span class="special">)</span>
  185. <span class="special">]</span>
  186. <span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">cref</span><span class="special">(</span><span class="identifier">commit</span><span class="special">)</span>
  187. <span class="special">);</span>
  188. <span class="comment">// ...</span>
  189. <span class="identifier">commit</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
  190. </pre>
  191. <p>
  192. Note the following issues with this approach:
  193. </p>
  194. <div class="orderedlist"><ol class="orderedlist" type="1">
  195. <li class="listitem">
  196. <a href="http://www.boost.org/libs/lambda" target="_top">Boost.Lambda</a> expressions
  197. are hard to write correctly (e.g., overloaded functions must be explicitly
  198. casted, as demonstrated in the example above).
  199. </li>
  200. <li class="listitem">
  201. The condition in the <code class="computeroutput"><span class="identifier">if_</span></code>
  202. expression refers to <code class="computeroutput"><span class="identifier">commit</span></code>
  203. variable indirectly through the <code class="computeroutput"><span class="identifier">_1</span></code>
  204. placeholder reducing readability.
  205. </li>
  206. <li class="listitem">
  207. Setting a breakpoint inside <code class="computeroutput"><span class="identifier">if_</span><span class="special">[...]</span></code> requires in-depth knowledge of <a href="http://www.boost.org/libs/lambda" target="_top">Boost.Lambda</a> and debugging
  208. techniques.
  209. </li>
  210. </ol></div>
  211. <p>
  212. This code will look much better with C++11 lambdas:
  213. </p>
  214. <pre class="programlisting"><span class="identifier">ON_BLOCK_EXIT</span><span class="special">(</span>
  215. <span class="special">[</span><span class="identifier">currency_rate_inserted</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">commit</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">rates</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">currency</span><span class="special">]()</span> <span class="special">{</span>
  216. <span class="keyword">if</span><span class="special">(</span><span class="identifier">currency_rate_inserted</span> <span class="special">&amp;&amp;</span> <span class="special">!</span><span class="identifier">commit</span><span class="special">)</span> <span class="identifier">rates</span><span class="special">.</span><span class="identifier">erase</span><span class="special">(</span><span class="identifier">currency</span><span class="special">);</span>
  217. <span class="special">}</span>
  218. <span class="special">);</span>
  219. <span class="comment">// ...</span>
  220. <span class="identifier">commit</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
  221. </pre>
  222. <p>
  223. With <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a> we can simply do the
  224. following (see also <a href="../../../example/scope_guard.cpp" target="_top"><code class="literal">scope_guard.cpp</code></a>):
  225. </p>
  226. <p>
  227. </p>
  228. <pre class="programlisting"><span class="identifier">BOOST_SCOPE_EXIT</span><span class="special">(</span><span class="identifier">currency_rate_inserted</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">commit</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">rates</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">currency</span><span class="special">)</span> <span class="special">{</span>
  229. <span class="keyword">if</span><span class="special">(</span><span class="identifier">currency_rate_inserted</span> <span class="special">&amp;&amp;</span> <span class="special">!</span><span class="identifier">commit</span><span class="special">)</span> <span class="identifier">rates</span><span class="special">.</span><span class="identifier">erase</span><span class="special">(</span><span class="identifier">currency</span><span class="special">);</span>
  230. <span class="special">}</span> <span class="identifier">BOOST_SCOPE_EXIT_END</span>
  231. <span class="comment">// ...</span>
  232. <span class="identifier">commit</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
  233. </pre>
  234. <p>
  235. </p>
  236. <h4>
  237. <a name="scope_exit.alternatives.h3"></a>
  238. <span class="phrase"><a name="scope_exit.alternatives.the_d_programming_language"></a></span><a class="link" href="alternatives.html#scope_exit.alternatives.the_d_programming_language">The
  239. D Programming Language</a>
  240. </h4>
  241. <p>
  242. <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a> is similar to <a href="http://www.digitalmars.com/d/2.0/statement.html#ScopeGuardStatement" target="_top">scope(exit)</a>
  243. feature built into the <a href="http://www.digitalmars.com/d/index.html" target="_top">D</a>
  244. programming language.
  245. </p>
  246. <p>
  247. A curious reader may notice that the library does not implement <code class="computeroutput"><span class="identifier">scope</span><span class="special">(</span><span class="identifier">success</span><span class="special">)</span></code> and <code class="computeroutput"><span class="identifier">scope</span><span class="special">(</span><span class="identifier">failure</span><span class="special">)</span></code> of the <a href="http://www.digitalmars.com/d/index.html" target="_top">D</a>
  248. language. Unfortunately, these are not possible in C++ because failure or success
  249. conditions cannot be determined by calling <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">uncaught_exception</span></code>
  250. (see <a href="http://www.gotw.ca/gotw/047.htm" target="_top">Guru of the Week #47</a>
  251. for details about <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">uncaught_exception</span></code> and if it has any good
  252. use at all). However, this is not a big problem because these two <a href="http://www.digitalmars.com/d/index.html" target="_top">D</a>'s
  253. constructs can be expressed in terms of <a href="http://www.digitalmars.com/d/2.0/statement.html#ScopeGuardStatement" target="_top">scope(exit)</a>
  254. and a <code class="computeroutput"><span class="keyword">bool</span> <span class="identifier">commit</span></code>
  255. variable (similarly to some examples presented in the <a class="link" href="tutorial.html" title="Tutorial">Tutorial</a>
  256. section).
  257. </p>
  258. <h4>
  259. <a name="scope_exit.alternatives.h4"></a>
  260. <span class="phrase"><a name="scope_exit.alternatives.c__11_lambdas"></a></span><a class="link" href="alternatives.html#scope_exit.alternatives.c__11_lambdas">C++11
  261. Lambdas</a>
  262. </h4>
  263. <p>
  264. Using C++11 lambdas, it is relatively easy to implement the <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a>
  265. construct. For example (see also <a href="../../../example/world_cxx11_lambda.cpp" target="_top"><code class="literal">world_cxx11_lambda.cpp</code></a>):
  266. </p>
  267. <p>
  268. </p>
  269. <pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">functional</span><span class="special">&gt;</span>
  270. <span class="keyword">struct</span> <span class="identifier">scope_exit</span> <span class="special">{</span>
  271. <span class="identifier">scope_exit</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span><span class="keyword">void</span> <span class="special">(</span><span class="keyword">void</span><span class="special">)&gt;</span> <span class="identifier">f</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">f_</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span> <span class="special">{}</span>
  272. <span class="special">~</span><span class="identifier">scope_exit</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">f_</span><span class="special">();</span> <span class="special">}</span>
  273. <span class="keyword">private</span><span class="special">:</span>
  274. <span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span><span class="keyword">void</span> <span class="special">(</span><span class="keyword">void</span><span class="special">)&gt;</span> <span class="identifier">f_</span><span class="special">;</span>
  275. <span class="special">};</span>
  276. <span class="keyword">void</span> <span class="identifier">world</span><span class="special">::</span><span class="identifier">add_person</span><span class="special">(</span><span class="identifier">person</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">a_person</span><span class="special">)</span> <span class="special">{</span>
  277. <span class="keyword">bool</span> <span class="identifier">commit</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
  278. <span class="identifier">persons_</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">a_person</span><span class="special">);</span>
  279. <span class="identifier">scope_exit</span> <span class="identifier">on_exit1</span><span class="special">([&amp;</span><span class="identifier">commit</span><span class="special">,</span> <span class="keyword">this</span><span class="special">](</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Use C++11 lambda.</span>
  280. <span class="keyword">if</span><span class="special">(!</span><span class="identifier">commit</span><span class="special">)</span> <span class="identifier">persons_</span><span class="special">.</span><span class="identifier">pop_back</span><span class="special">();</span> <span class="comment">// `persons_` via captured `this`.</span>
  281. <span class="special">});</span>
  282. <span class="comment">// ...</span>
  283. <span class="identifier">commit</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
  284. <span class="special">}</span>
  285. </pre>
  286. <p>
  287. </p>
  288. <p>
  289. However, this library allows to program the <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a>
  290. construct in a way that is portable between C++03 and C++11 compilers.
  291. </p>
  292. </div>
  293. <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
  294. <td align="left"></td>
  295. <td align="right"><div class="copyright-footer">Copyright &#169; 2006-2012 Alexander Nasonov, Lorenzo Caminiti<p>
  296. Distributed under the Boost Software License, Version 1.0 (see accompanying
  297. file LICENSE_1_0.txt or a copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
  298. </p>
  299. </div></td>
  300. </tr></table>
  301. <hr>
  302. <div class="spirit-nav">
  303. <a accesskey="p" href="tutorial.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="no_variadic_macros.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
  304. </div>
  305. </body>
  306. </html>