]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/scope_exit/doc/html/scope_exit/tutorial.html
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / scope_exit / doc / html / scope_exit / tutorial.html
1 <html>
2 <head>
3 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
4 <title>Tutorial</title>
5 <link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
6 <meta name="generator" content="DocBook XSL Stylesheets V1.78.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="getting_started.html" title="Getting Started">
10 <link rel="next" href="alternatives.html" title="Annex: Alternatives">
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.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="alternatives.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.tutorial"></a><a class="link" href="tutorial.html" title="Tutorial">Tutorial</a>
28 </h2></div></div></div>
29 <div class="toc"><dl class="toc">
30 <dt><span class="section"><a href="tutorial.html#scope_exit.tutorial.capturing_variables">Capturing Variables</a></span></dt>
31 <dt><span class="section"><a href="tutorial.html#scope_exit.tutorial.capturing_the_object__this_">Capturing
32 The Object <code class="computeroutput"><span class="keyword">this</span></code></a></span></dt>
33 <dt><span class="section"><a href="tutorial.html#scope_exit.tutorial.capturing_no_variable">Capturing
34 No Variable</a></span></dt>
35 <dt><span class="section"><a href="tutorial.html#scope_exit.tutorial.capturing_all_variables__c__11_only_">Capturing
36 All Variables (C++11 Only)</a></span></dt>
37 <dt><span class="section"><a href="tutorial.html#scope_exit.tutorial.template_workaround__gcc_">Template
38 Workaround (GCC)</a></span></dt>
39 <dt><span class="section"><a href="tutorial.html#scope_exit.tutorial.same_line_expansions">Same Line Expansions</a></span></dt>
40 </dl></div>
41 <p>
42 This section illustrates how to use this library.
43 </p>
44 <div class="section">
45 <div class="titlepage"><div><div><h3 class="title">
46 <a name="scope_exit.tutorial.capturing_variables"></a><a class="link" href="tutorial.html#scope_exit.tutorial.capturing_variables" title="Capturing Variables">Capturing Variables</a>
47 </h3></div></div></div>
48 <p>
49 Imagine that we want to make many modifications to data members of some
50 <code class="computeroutput"><span class="identifier">world</span></code> class in its <code class="computeroutput"><span class="identifier">world</span><span class="special">::</span><span class="identifier">add_person</span></code> member function. We start with
51 adding a new <code class="computeroutput"><span class="identifier">person</span></code> object
52 to a vector of persons:
53 </p>
54 <pre class="programlisting"><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>
55 <span class="keyword">bool</span> <span class="identifier">commit</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
56
57 <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> <span class="comment">// (1) direct action</span>
58 <span class="special">...</span>
59 </pre>
60 <p>
61 Some operations down the road may throw an exception and all changes to involved
62 objects should be rolled back. This all-or-nothing semantic is also known
63 as <a href="http://www.research.att.com/~bs/glossary.html#Gstrong-guarantee" target="_top">strong
64 guarantee</a>.
65 </p>
66 <p>
67 In particular, the last added person must be deleted from <code class="computeroutput"><span class="identifier">persons_</span></code>
68 if the function throws. All we need is to define a delayed action (release
69 of a resource) right after the direct action (resource acquisition). For
70 example (see also <a href="../../../test/world.cpp" target="_top"><code class="literal">world.cpp</code></a>):
71 </p>
72 <p>
73 </p>
74 <pre class="programlisting"><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>
75 <span class="keyword">bool</span> <span class="identifier">commit</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
76
77 <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> <span class="comment">// (1) direct action</span>
78 <span class="comment">// Following block is executed when the enclosing scope exits.</span>
79 <span class="identifier">BOOST_SCOPE_EXIT</span><span class="special">(&amp;</span><span class="identifier">commit</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">persons_</span><span class="special">)</span> <span class="special">{</span>
80 <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">// (2) rollback action</span>
81 <span class="special">}</span> <span class="identifier">BOOST_SCOPE_EXIT_END</span>
82
83 <span class="comment">// ... // (3) other operations</span>
84
85 <span class="identifier">commit</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span> <span class="comment">// (4) disable rollback actions</span>
86 <span class="special">}</span>
87 </pre>
88 <p>
89 </p>
90 <p>
91 The block below point <code class="literal">(1)</code> is a <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a>
92 declaration. Unlike point <code class="literal">(1)</code>, an execution of the <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a> body will be delayed until the
93 end of the current scope. In this case it will be executed either after point
94 <code class="literal">(4)</code> or on any exception. (On various versions of the GCC
95 compiler, it is necessary to use <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_TPL.html" title="Macro BOOST_SCOPE_EXIT_TPL">BOOST_SCOPE_EXIT_TPL</a></code>
96 instead of <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT.html" title="Macro BOOST_SCOPE_EXIT">BOOST_SCOPE_EXIT</a></code>
97 within templates, see later in this section for details.)
98 </p>
99 <p>
100 The <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a> declaration starts
101 with the <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT.html" title="Macro BOOST_SCOPE_EXIT">BOOST_SCOPE_EXIT</a></code> macro
102 invocation which accepts a comma-separated list of captured variables (a
103 <a href="http://www.boost.org/libs/preprocessor" target="_top">Boost.Preprocessor</a>
104 sequence is also accepted for compilers that do not support variadic macros
105 and for backward compatibility with older versions of this library, see the
106 <a class="link" href="no_variadic_macros.html" title="Annex: No Variadic Macros">No Variadic Macros</a> section).
107 If a capture starts with the ampersand sign <code class="computeroutput"><span class="special">&amp;</span></code>,
108 a reference to the captured variable will be available inside the <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a>
109 body; otherwise, a copy of the variable will be made after the <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a>
110 declaration at point <code class="literal">(1)</code> and only the copy will be available
111 inside the body (in this case, the captured variable's type must be <a href="http://www.boost.org/doc/libs/release/doc/html/CopyConstructible.html" target="_top"><code class="computeroutput"><span class="identifier">CopyConstructible</span></code></a>).
112 </p>
113 <p>
114 In the example above, the variables <code class="computeroutput"><span class="identifier">commit</span></code>
115 and <code class="computeroutput"><span class="identifier">persons_</span></code> are captured
116 by reference because the final value of the <code class="computeroutput"><span class="identifier">commit</span></code>
117 variable should be used to determine whether to execute rollback actions
118 or not, and the action should modify the <code class="computeroutput"><span class="identifier">persons_</span></code>
119 object, not its copy. This is the most common case but passing a variable
120 by value is sometimes useful as well.
121 </p>
122 <p>
123 Finally, the end of the <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a>
124 body must be marked by the <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_END.html" title="Macro BOOST_SCOPE_EXIT_END">BOOST_SCOPE_EXIT_END</a></code>
125 macro which must follow the closing curly bracket <code class="computeroutput"><span class="special">}</span></code>
126 of the <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a> body.
127 </p>
128 <div class="important"><table border="0" summary="Important">
129 <tr>
130 <td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td>
131 <th align="left">Important</th>
132 </tr>
133 <tr><td align="left" valign="top"><p>
134 In order to comply with the <a href="http://www.stlport.org/doc/exception_safety.html" target="_top">STL
135 exception safety requirements</a>, the <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a>
136 body must never throw (because the library implementation executes the
137 body within a destructor call). This is true for all <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a>
138 macros (including <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_TPL.html" title="Macro BOOST_SCOPE_EXIT_TPL">BOOST_SCOPE_EXIT_TPL</a></code>
139 and <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ALL.html" title="Macro BOOST_SCOPE_EXIT_ALL">BOOST_SCOPE_EXIT_ALL</a></code>
140 seen below) on both C++03 and C++11.
141 </p></td></tr>
142 </table></div>
143 <p>
144 Consider a more complex example where <code class="computeroutput"><span class="identifier">world</span><span class="special">::</span><span class="identifier">add_person</span></code>
145 can save intermediate states at some point and roll back to the last saved
146 state. We use <code class="computeroutput"><span class="identifier">person</span><span class="special">::</span><span class="identifier">evolution_</span></code> to store a version of the changes
147 and increment it to cancel all rollback actions associated with those changes.
148 If we pass a current value of <code class="computeroutput"><span class="identifier">evolution_</span></code>
149 stored in the <code class="computeroutput"><span class="identifier">checkpoint</span></code>
150 variable by value, it remains unchanged within the <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a>
151 body so we can compare it with the final value of <code class="computeroutput"><span class="identifier">evolution_</span></code>.
152 If the latter was not incremented since we saved it, the rollback action
153 inside the <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a> body should
154 be executed. For example (see also <a href="../../../test/world_checkpoint.cpp" target="_top"><code class="literal">world_checkpoint.cpp</code></a>):
155 </p>
156 <p>
157 </p>
158 <pre class="programlisting"><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>
159 <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>
160
161 <span class="comment">// This block must be no-throw.</span>
162 <span class="identifier">person</span><span class="special">&amp;</span> <span class="identifier">p</span> <span class="special">=</span> <span class="identifier">persons_</span><span class="special">.</span><span class="identifier">back</span><span class="special">();</span>
163 <span class="identifier">person</span><span class="special">::</span><span class="identifier">evolution_t</span> <span class="identifier">checkpoint</span> <span class="special">=</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">evolution</span><span class="special">;</span>
164 <span class="identifier">BOOST_SCOPE_EXIT</span><span class="special">(</span><span class="identifier">checkpoint</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">p</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">persons_</span><span class="special">)</span> <span class="special">{</span>
165 <span class="keyword">if</span><span class="special">(</span><span class="identifier">checkpoint</span> <span class="special">==</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">evolution</span><span class="special">)</span> <span class="identifier">persons_</span><span class="special">.</span><span class="identifier">pop_back</span><span class="special">();</span>
166 <span class="special">}</span> <span class="identifier">BOOST_SCOPE_EXIT_END</span>
167
168 <span class="comment">// ...</span>
169
170 <span class="identifier">checkpoint</span> <span class="special">=</span> <span class="special">++</span><span class="identifier">p</span><span class="special">.</span><span class="identifier">evolution</span><span class="special">;</span>
171
172 <span class="comment">// Assign new identifier to the person.</span>
173 <span class="identifier">person</span><span class="special">::</span><span class="identifier">id_t</span> <span class="keyword">const</span> <span class="identifier">prev_id</span> <span class="special">=</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">id</span><span class="special">;</span>
174 <span class="identifier">p</span><span class="special">.</span><span class="identifier">id</span> <span class="special">=</span> <span class="identifier">next_id_</span><span class="special">++;</span>
175 <span class="identifier">BOOST_SCOPE_EXIT</span><span class="special">(</span><span class="identifier">checkpoint</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">p</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">next_id_</span><span class="special">,</span> <span class="identifier">prev_id</span><span class="special">)</span> <span class="special">{</span>
176 <span class="keyword">if</span><span class="special">(</span><span class="identifier">checkpoint</span> <span class="special">==</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">evolution</span><span class="special">)</span> <span class="special">{</span>
177 <span class="identifier">next_id_</span> <span class="special">=</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">id</span><span class="special">;</span>
178 <span class="identifier">p</span><span class="special">.</span><span class="identifier">id</span> <span class="special">=</span> <span class="identifier">prev_id</span><span class="special">;</span>
179 <span class="special">}</span>
180 <span class="special">}</span> <span class="identifier">BOOST_SCOPE_EXIT_END</span>
181
182 <span class="comment">// ...</span>
183
184 <span class="identifier">checkpoint</span> <span class="special">=</span> <span class="special">++</span><span class="identifier">p</span><span class="special">.</span><span class="identifier">evolution</span><span class="special">;</span>
185 <span class="special">}</span>
186 </pre>
187 <p>
188 </p>
189 <p>
190 When multiple <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a> blocks are
191 declared within the same enclosing scope, the <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a>
192 bodies are executed in the reversed order of their declarations.
193 </p>
194 </div>
195 <div class="section">
196 <div class="titlepage"><div><div><h3 class="title">
197 <a name="scope_exit.tutorial.capturing_the_object__this_"></a><a class="link" href="tutorial.html#scope_exit.tutorial.capturing_the_object__this_" title="Capturing The Object this">Capturing
198 The Object <code class="computeroutput"><span class="keyword">this</span></code></a>
199 </h3></div></div></div>
200 <p>
201 Within a member function, it is also possible to capture the object <code class="computeroutput"><span class="keyword">this</span></code>. However, the special symbol <code class="computeroutput"><span class="identifier">this_</span></code> must be used instead of <code class="computeroutput"><span class="keyword">this</span></code> in the <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a>
202 declaration and body to capture and access the object. For example (see also
203 <a href="../../../test/world_this.cpp" target="_top"><code class="literal">world_this.cpp</code></a>):
204 </p>
205 <p>
206 </p>
207 <pre class="programlisting"><span class="identifier">BOOST_SCOPE_EXIT</span><span class="special">(&amp;</span><span class="identifier">commit</span><span class="special">,</span> <span class="identifier">this_</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Capture object `this_`.</span>
208 <span class="keyword">if</span><span class="special">(!</span><span class="identifier">commit</span><span class="special">)</span> <span class="identifier">this_</span><span class="special">-&gt;</span><span class="identifier">persons_</span><span class="special">.</span><span class="identifier">pop_back</span><span class="special">();</span>
209 <span class="special">}</span> <span class="identifier">BOOST_SCOPE_EXIT_END</span>
210 </pre>
211 <p>
212 </p>
213 <p>
214 It is not possible to capture the object <code class="computeroutput"><span class="identifier">this_</span></code>
215 by reference because C++ does not allow to take a reference to <code class="computeroutput"><span class="keyword">this</span></code>. If the enclosing member function is
216 constant then the captured object will also be constant, otherwise the captured
217 object will be mutable.
218 </p>
219 </div>
220 <div class="section">
221 <div class="titlepage"><div><div><h3 class="title">
222 <a name="scope_exit.tutorial.capturing_no_variable"></a><a class="link" href="tutorial.html#scope_exit.tutorial.capturing_no_variable" title="Capturing No Variable">Capturing
223 No Variable</a>
224 </h3></div></div></div>
225 <p>
226 A <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a> declaration can also
227 capture no variable. In this case, the list of captured variables is replaced
228 by the <code class="computeroutput"><span class="keyword">void</span></code> keyword (similarly
229 to the C++ syntax that allows to declare a function with no parameter using
230 <code class="literal"><span class="emphasis"><em>result-type function-name</em></span></code><code class="computeroutput"><span class="special">(</span><span class="keyword">void</span><span class="special">)</span></code>).
231 <a href="#ftn.scope_exit.tutorial.capturing_no_variable.f0" class="footnote" name="scope_exit.tutorial.capturing_no_variable.f0"><sup class="footnote">[3]</sup></a> For example, this can be useful when the <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a>
232 body only needs to access global variables (see also <a href="../../../test/world_void.cpp" target="_top"><code class="literal">world_void.cpp</code></a>):
233 </p>
234 <p>
235 </p>
236 <pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">world_t</span> <span class="special">{</span>
237 <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;</span> <span class="identifier">persons</span><span class="special">;</span>
238 <span class="keyword">bool</span> <span class="identifier">commit</span><span class="special">;</span>
239 <span class="special">}</span> <span class="identifier">world</span><span class="special">;</span> <span class="comment">// Global variable.</span>
240
241 <span class="keyword">void</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>
242 <span class="identifier">world</span><span class="special">.</span><span class="identifier">commit</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
243 <span class="identifier">world</span><span class="special">.</span><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>
244
245 <span class="identifier">BOOST_SCOPE_EXIT</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// No captures.</span>
246 <span class="keyword">if</span><span class="special">(!</span><span class="identifier">world</span><span class="special">.</span><span class="identifier">commit</span><span class="special">)</span> <span class="identifier">world</span><span class="special">.</span><span class="identifier">persons</span><span class="special">.</span><span class="identifier">pop_back</span><span class="special">();</span>
247 <span class="special">}</span> <span class="identifier">BOOST_SCOPE_EXIT_END</span>
248
249 <span class="comment">// ...</span>
250
251 <span class="identifier">world</span><span class="special">.</span><span class="identifier">commit</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
252 <span class="special">}</span>
253 </pre>
254 <p>
255 </p>
256 <p>
257 (Both compilers with and without variadic macros use this same syntax for
258 capturing no variable, see the <a class="link" href="no_variadic_macros.html" title="Annex: No Variadic Macros">No
259 Variadic Macros</a> section for more information.)
260 </p>
261 </div>
262 <div class="section">
263 <div class="titlepage"><div><div><h3 class="title">
264 <a name="scope_exit.tutorial.capturing_all_variables__c__11_only_"></a><a class="link" href="tutorial.html#scope_exit.tutorial.capturing_all_variables__c__11_only_" title="Capturing All Variables (C++11 Only)">Capturing
265 All Variables (C++11 Only)</a>
266 </h3></div></div></div>
267 <p>
268 On C++11 compliers, it is also possible to capture all the variables in scope
269 without naming them one-by-one using the special macro <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ALL.html" title="Macro BOOST_SCOPE_EXIT_ALL">BOOST_SCOPE_EXIT_ALL</a></code>
270 instead of <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT.html" title="Macro BOOST_SCOPE_EXIT">BOOST_SCOPE_EXIT</a></code>.
271 <a href="#ftn.scope_exit.tutorial.capturing_all_variables__c__11_only_.f0" class="footnote" name="scope_exit.tutorial.capturing_all_variables__c__11_only_.f0"><sup class="footnote">[4]</sup></a>
272 </p>
273 <p>
274 Following the same syntax adopted by C++11 lambda functions, the <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ALL.html" title="Macro BOOST_SCOPE_EXIT_ALL">BOOST_SCOPE_EXIT_ALL</a></code> macro accepts
275 a comma-separated list of captures which must start with either <code class="computeroutput"><span class="special">&amp;</span></code> or <code class="computeroutput"><span class="special">=</span></code>
276 to capture all variables in scope respectively by reference or by value (note
277 that no variable name is specified by these leading captures). Additional
278 captures of specific variables can follow the leading <code class="computeroutput"><span class="special">&amp;</span></code>
279 or <code class="computeroutput"><span class="special">=</span></code> and they will override
280 the default reference or value captures. For example (see also <a href="../../../test/world_checkpoint_all.cpp" target="_top"><code class="literal">world_checkpoint_all.cpp</code></a>):
281 </p>
282 <p>
283 </p>
284 <pre class="programlisting"><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>
285 <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>
286
287 <span class="comment">// This block must be no-throw.</span>
288 <span class="identifier">person</span><span class="special">&amp;</span> <span class="identifier">p</span> <span class="special">=</span> <span class="identifier">persons_</span><span class="special">.</span><span class="identifier">back</span><span class="special">();</span>
289 <span class="identifier">person</span><span class="special">::</span><span class="identifier">evolution_t</span> <span class="identifier">checkpoint</span> <span class="special">=</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">evolution</span><span class="special">;</span>
290 <span class="comment">// Capture all by reference `&amp;`, but `checkpoint` and `this` (C++11 only).</span>
291 <span class="identifier">BOOST_SCOPE_EXIT_ALL</span><span class="special">(&amp;,</span> <span class="identifier">checkpoint</span><span class="special">,</span> <span class="keyword">this</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Use `this` (not `this_`).</span>
292 <span class="keyword">if</span><span class="special">(</span><span class="identifier">checkpoint</span> <span class="special">==</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">evolution</span><span class="special">)</span> <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">persons_</span><span class="special">.</span><span class="identifier">pop_back</span><span class="special">();</span>
293 <span class="special">};</span> <span class="comment">// Use `;` (not `SCOPE_EXIT_END`).</span>
294
295 <span class="comment">// ...</span>
296
297 <span class="identifier">checkpoint</span> <span class="special">=</span> <span class="special">++</span><span class="identifier">p</span><span class="special">.</span><span class="identifier">evolution</span><span class="special">;</span>
298
299 <span class="comment">// Assign new identifier to the person.</span>
300 <span class="identifier">person</span><span class="special">::</span><span class="identifier">id_t</span> <span class="keyword">const</span> <span class="identifier">prev_id</span> <span class="special">=</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">id</span><span class="special">;</span>
301 <span class="identifier">p</span><span class="special">.</span><span class="identifier">id</span> <span class="special">=</span> <span class="identifier">next_id_</span><span class="special">++;</span>
302 <span class="comment">// Capture all by value `=`, but `p` (C++11 only).</span>
303 <span class="identifier">BOOST_SCOPE_EXIT_ALL</span><span class="special">(=,</span> <span class="special">&amp;</span><span class="identifier">p</span><span class="special">)</span> <span class="special">{</span>
304 <span class="keyword">if</span><span class="special">(</span><span class="identifier">checkpoint</span> <span class="special">==</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">evolution</span><span class="special">)</span> <span class="special">{</span>
305 <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">next_id_</span> <span class="special">=</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">id</span><span class="special">;</span>
306 <span class="identifier">p</span><span class="special">.</span><span class="identifier">id</span> <span class="special">=</span> <span class="identifier">prev_id</span><span class="special">;</span>
307 <span class="special">}</span>
308 <span class="special">};</span>
309
310 <span class="comment">// ...</span>
311
312 <span class="identifier">checkpoint</span> <span class="special">=</span> <span class="special">++</span><span class="identifier">p</span><span class="special">.</span><span class="identifier">evolution</span><span class="special">;</span>
313 <span class="special">}</span>
314 </pre>
315 <p>
316 </p>
317 <p>
318 The first <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a> declaration captures
319 all variables in scope by reference but the variable <code class="computeroutput"><span class="identifier">checkpoint</span></code>
320 and the object <code class="computeroutput"><span class="keyword">this</span></code> which are
321 explicitly captured by value (in particular, <code class="computeroutput"><span class="identifier">p</span></code>
322 and <code class="computeroutput"><span class="identifier">persons_</span></code> are implicitly
323 captured by reference here). The second <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a>
324 declaration instead captures all variables in scope by value but <code class="computeroutput"><span class="identifier">p</span></code> which is explicitly captured by reference
325 (in particular, <code class="computeroutput"><span class="identifier">checkpoint</span></code>,
326 <code class="computeroutput"><span class="identifier">prev_id</span></code>, and <code class="computeroutput"><span class="keyword">this</span></code> are implicitly captured by value here).
327 </p>
328 <p>
329 Note that the <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ALL.html" title="Macro BOOST_SCOPE_EXIT_ALL">BOOST_SCOPE_EXIT_ALL</a></code>
330 macro follows the C++11 lambda function syntax which is unfortunately different
331 from the <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT.html" title="Macro BOOST_SCOPE_EXIT">BOOST_SCOPE_EXIT</a></code> macro
332 syntax. In particular:
333 </p>
334 <div class="orderedlist"><ol class="orderedlist" type="1">
335 <li class="listitem">
336 The <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ALL.html" title="Macro BOOST_SCOPE_EXIT_ALL">BOOST_SCOPE_EXIT_ALL</a></code>
337 macro cannot capture data members without capturing the object <code class="computeroutput"><span class="keyword">this</span></code> while that is not the case for <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT.html" title="Macro BOOST_SCOPE_EXIT">BOOST_SCOPE_EXIT</a></code>. <a href="#ftn.scope_exit.tutorial.capturing_all_variables__c__11_only_.f1" class="footnote" name="scope_exit.tutorial.capturing_all_variables__c__11_only_.f1"><sup class="footnote">[5]</sup></a>
338 </li>
339 <li class="listitem">
340 The <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ALL.html" title="Macro BOOST_SCOPE_EXIT_ALL">BOOST_SCOPE_EXIT_ALL</a></code>
341 macro captures the object in scope using <code class="computeroutput"><span class="keyword">this</span></code>
342 instead of <code class="computeroutput"><span class="identifier">this_</span></code>. <a href="#ftn.scope_exit.tutorial.capturing_all_variables__c__11_only_.f2" class="footnote" name="scope_exit.tutorial.capturing_all_variables__c__11_only_.f2"><sup class="footnote">[6]</sup></a>
343 </li>
344 <li class="listitem">
345 The <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ALL.html" title="Macro BOOST_SCOPE_EXIT_ALL">BOOST_SCOPE_EXIT_ALL</a></code>
346 body is terminated by a semicolon <code class="computeroutput"><span class="special">;</span></code>
347 instead than by the <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_END.html" title="Macro BOOST_SCOPE_EXIT_END">BOOST_SCOPE_EXIT_END</a></code>
348 macro.
349 </li>
350 </ol></div>
351 <p>
352 If programmers define the configuration macro <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_CONFIG_USE_LAMBDAS.html" title="Macro BOOST_SCOPE_EXIT_CONFIG_USE_LAMBDAS">BOOST_SCOPE_EXIT_CONFIG_USE_LAMBDAS</a></code>
353 then the <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT.html" title="Macro BOOST_SCOPE_EXIT">BOOST_SCOPE_EXIT</a></code> macro
354 implementation will use C++11 lamda functions and the <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT.html" title="Macro BOOST_SCOPE_EXIT">BOOST_SCOPE_EXIT</a></code>
355 macro will follow the same syntax of <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ALL.html" title="Macro BOOST_SCOPE_EXIT_ALL">BOOST_SCOPE_EXIT_ALL</a></code>
356 macro, which is the C++11 lambda function syntax. However, <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT.html" title="Macro BOOST_SCOPE_EXIT">BOOST_SCOPE_EXIT</a></code>
357 will no longer be backward compatible and older code using <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT.html" title="Macro BOOST_SCOPE_EXIT">BOOST_SCOPE_EXIT</a></code>
358 might no longer compile (if data members were explicitly captured).
359 </p>
360 </div>
361 <div class="section">
362 <div class="titlepage"><div><div><h3 class="title">
363 <a name="scope_exit.tutorial.template_workaround__gcc_"></a><a class="link" href="tutorial.html#scope_exit.tutorial.template_workaround__gcc_" title="Template Workaround (GCC)">Template
364 Workaround (GCC)</a>
365 </h3></div></div></div>
366 <p>
367 Various versions of the GCC compiler do not compile <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT.html" title="Macro BOOST_SCOPE_EXIT">BOOST_SCOPE_EXIT</a></code>
368 inside templates (see the <a href="../reference.html" target="_top">Reference</a> section
369 for more information). As a workaround, <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_TPL.html" title="Macro BOOST_SCOPE_EXIT_TPL">BOOST_SCOPE_EXIT_TPL</a></code>
370 should be used instead of <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT.html" title="Macro BOOST_SCOPE_EXIT">BOOST_SCOPE_EXIT</a></code>
371 in these cases. <a href="#ftn.scope_exit.tutorial.template_workaround__gcc_.f0" class="footnote" name="scope_exit.tutorial.template_workaround__gcc_.f0"><sup class="footnote">[7]</sup></a> The <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_TPL.html" title="Macro BOOST_SCOPE_EXIT_TPL">BOOST_SCOPE_EXIT_TPL</a></code>
372 macro has the exact same syntax of <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT.html" title="Macro BOOST_SCOPE_EXIT">BOOST_SCOPE_EXIT</a></code>.
373 For example (see also <a href="../../../test/world_tpl.cpp" target="_top"><code class="literal">world_tpl.cpp</code></a>):
374 </p>
375 <p>
376 </p>
377 <pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Person</span><span class="special">&gt;</span>
378 <span class="keyword">void</span> <span class="identifier">world</span><span class="special">&lt;</span><span class="identifier">Person</span><span class="special">&gt;::</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>
379 <span class="keyword">bool</span> <span class="identifier">commit</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
380 <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>
381
382 <span class="identifier">BOOST_SCOPE_EXIT_TPL</span><span class="special">(&amp;</span><span class="identifier">commit</span><span class="special">,</span> <span class="identifier">this_</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Use `_TPL` postfix.</span>
383 <span class="keyword">if</span><span class="special">(!</span><span class="identifier">commit</span><span class="special">)</span> <span class="identifier">this_</span><span class="special">-&gt;</span><span class="identifier">persons_</span><span class="special">.</span><span class="identifier">pop_back</span><span class="special">();</span>
384 <span class="special">}</span> <span class="identifier">BOOST_SCOPE_EXIT_END</span>
385
386 <span class="comment">// ...</span>
387
388 <span class="identifier">commit</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
389 <span class="special">}</span>
390 </pre>
391 <p>
392 </p>
393 <p>
394 It is recommended to always use <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_TPL.html" title="Macro BOOST_SCOPE_EXIT_TPL">BOOST_SCOPE_EXIT_TPL</a></code>
395 within templates so to maximize portability among different compilers.
396 </p>
397 </div>
398 <div class="section">
399 <div class="titlepage"><div><div><h3 class="title">
400 <a name="scope_exit.tutorial.same_line_expansions"></a><a class="link" href="tutorial.html#scope_exit.tutorial.same_line_expansions" title="Same Line Expansions">Same Line Expansions</a>
401 </h3></div></div></div>
402 <p>
403 In general, it is not possible to expand the <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT.html" title="Macro BOOST_SCOPE_EXIT">BOOST_SCOPE_EXIT</a></code>,
404 <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_TPL.html" title="Macro BOOST_SCOPE_EXIT_TPL">BOOST_SCOPE_EXIT_TPL</a></code>,
405 <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_END.html" title="Macro BOOST_SCOPE_EXIT_END">BOOST_SCOPE_EXIT_END</a></code>, and
406 <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ALL.html" title="Macro BOOST_SCOPE_EXIT_ALL">BOOST_SCOPE_EXIT_ALL</a></code> macros
407 multiple times on the same line. <a href="#ftn.scope_exit.tutorial.same_line_expansions.f0" class="footnote" name="scope_exit.tutorial.same_line_expansions.f0"><sup class="footnote">[8]</sup></a>
408 </p>
409 <p>
410 Therefore, this library provides additional macros <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ID.html" title="Macro BOOST_SCOPE_EXIT_ID">BOOST_SCOPE_EXIT_ID</a></code>,
411 <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ID_TPL.html" title="Macro BOOST_SCOPE_EXIT_ID_TPL">BOOST_SCOPE_EXIT_ID_TPL</a></code>,
412 <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_END_ID.html" title="Macro BOOST_SCOPE_EXIT_END_ID">BOOST_SCOPE_EXIT_END_ID</a></code>,
413 and <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ALL_ID.html" title="Macro BOOST_SCOPE_EXIT_ALL_ID">BOOST_SCOPE_EXIT_ALL_ID</a></code>
414 which can be expanded multiple times on the same line as long as programmers
415 specify a unique identifiers as the macros' first parameters. The unique
416 identifier can be any token (not just numeric) that can be concatenated by
417 the C++ preprocessor (e.g., <code class="computeroutput"><span class="identifier">scope_exit_number_1_at_line_123</span></code>).
418 <a href="#ftn.scope_exit.tutorial.same_line_expansions.f1" class="footnote" name="scope_exit.tutorial.same_line_expansions.f1"><sup class="footnote">[9]</sup></a>
419 </p>
420 <p>
421 The <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ID.html" title="Macro BOOST_SCOPE_EXIT_ID">BOOST_SCOPE_EXIT_ID</a></code>,
422 <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ID_TPL.html" title="Macro BOOST_SCOPE_EXIT_ID_TPL">BOOST_SCOPE_EXIT_ID_TPL</a></code>,
423 and <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ALL_ID.html" title="Macro BOOST_SCOPE_EXIT_ALL_ID">BOOST_SCOPE_EXIT_ALL_ID</a></code>
424 macros accept a capture list using the exact same syntax as <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT.html" title="Macro BOOST_SCOPE_EXIT">BOOST_SCOPE_EXIT</a></code>
425 and <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ALL.html" title="Macro BOOST_SCOPE_EXIT_ALL">BOOST_SCOPE_EXIT_ALL</a></code>
426 respectively. For example (see also <a href="../../../test/same_line.cpp" target="_top"><code class="literal">same_line.cpp</code></a>):
427 </p>
428 <p>
429 </p>
430 <pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">SCOPE_EXIT_INC_DEC</span><span class="special">(</span><span class="identifier">variable</span><span class="special">,</span> <span class="identifier">offset</span><span class="special">)</span> <span class="special">\</span>
431 <span class="identifier">BOOST_SCOPE_EXIT_ID</span><span class="special">(</span><span class="identifier">BOOST_PP_CAT</span><span class="special">(</span><span class="identifier">inc</span><span class="special">,</span> <span class="identifier">__LINE__</span><span class="special">),</span> <span class="comment">/* unique ID */</span> <span class="special">\</span>
432 <span class="special">&amp;</span><span class="identifier">variable</span><span class="special">,</span> <span class="identifier">offset</span><span class="special">)</span> <span class="special">{</span> <span class="special">\</span>
433 <span class="identifier">variable</span> <span class="special">+=</span> <span class="identifier">offset</span><span class="special">;</span> <span class="special">\</span>
434 <span class="special">}</span> <span class="identifier">BOOST_SCOPE_EXIT_END_ID</span><span class="special">(</span><span class="identifier">BOOST_PP_CAT</span><span class="special">(</span><span class="identifier">inc</span><span class="special">,</span> <span class="identifier">__LINE__</span><span class="special">))</span> <span class="special">\</span>
435 <span class="special">\</span>
436 <span class="identifier">BOOST_SCOPE_EXIT_ID</span><span class="special">(</span><span class="identifier">BOOST_PP_CAT</span><span class="special">(</span><span class="identifier">dec</span><span class="special">,</span> <span class="identifier">__LINE__</span><span class="special">),</span> <span class="special">\</span>
437 <span class="special">&amp;</span><span class="identifier">variable</span><span class="special">,</span> <span class="identifier">offset</span><span class="special">)</span> <span class="special">{</span> <span class="special">\</span>
438 <span class="identifier">variable</span> <span class="special">-=</span> <span class="identifier">offset</span><span class="special">;</span> <span class="special">\</span>
439 <span class="special">}</span> <span class="identifier">BOOST_SCOPE_EXIT_END_ID</span><span class="special">(</span><span class="identifier">BOOST_PP_CAT</span><span class="special">(</span><span class="identifier">dec</span><span class="special">,</span> <span class="identifier">__LINE__</span><span class="special">))</span>
440
441 <span class="preprocessor">#define</span> <span class="identifier">SCOPE_EXIT_INC_DEC_TPL</span><span class="special">(</span><span class="identifier">variable</span><span class="special">,</span> <span class="identifier">offset</span><span class="special">)</span> <span class="special">\</span>
442 <span class="identifier">BOOST_SCOPE_EXIT_ID_TPL</span><span class="special">(</span><span class="identifier">BOOST_PP_CAT</span><span class="special">(</span><span class="identifier">inc</span><span class="special">,</span> <span class="identifier">__LINE__</span><span class="special">),</span> <span class="special">\</span>
443 <span class="special">&amp;</span><span class="identifier">variable</span><span class="special">,</span> <span class="identifier">offset</span><span class="special">)</span> <span class="special">{</span> <span class="special">\</span>
444 <span class="identifier">variable</span> <span class="special">+=</span> <span class="identifier">offset</span><span class="special">;</span> <span class="special">\</span>
445 <span class="special">}</span> <span class="identifier">BOOST_SCOPE_EXIT_END_ID</span><span class="special">(</span><span class="identifier">BOOST_PP_CAT</span><span class="special">(</span><span class="identifier">inc</span><span class="special">,</span> <span class="identifier">__LINE__</span><span class="special">))</span> <span class="special">\</span>
446 <span class="special">\</span>
447 <span class="identifier">BOOST_SCOPE_EXIT_ID_TPL</span><span class="special">(</span><span class="identifier">BOOST_PP_CAT</span><span class="special">(</span><span class="identifier">dec</span><span class="special">,</span> <span class="identifier">__LINE__</span><span class="special">),</span> <span class="special">\</span>
448 <span class="special">&amp;</span><span class="identifier">variable</span><span class="special">,</span> <span class="identifier">offset</span><span class="special">)</span> <span class="special">{</span> <span class="special">\</span>
449 <span class="identifier">variable</span> <span class="special">-=</span> <span class="identifier">offset</span><span class="special">;</span> <span class="special">\</span>
450 <span class="special">}</span> <span class="identifier">BOOST_SCOPE_EXIT_END_ID</span><span class="special">(</span><span class="identifier">BOOST_PP_CAT</span><span class="special">(</span><span class="identifier">dec</span><span class="special">,</span> <span class="identifier">__LINE__</span><span class="special">))</span>
451
452 <span class="preprocessor">#define</span> <span class="identifier">SCOPE_EXIT_ALL_INC_DEC</span><span class="special">(</span><span class="identifier">variable</span><span class="special">,</span> <span class="identifier">offset</span><span class="special">)</span> <span class="special">\</span>
453 <span class="identifier">BOOST_SCOPE_EXIT_ALL_ID</span><span class="special">(</span><span class="identifier">BOOST_PP_CAT</span><span class="special">(</span><span class="identifier">inc</span><span class="special">,</span> <span class="identifier">__LINE__</span><span class="special">),</span> <span class="special">\</span>
454 <span class="special">=,</span> <span class="special">&amp;</span><span class="identifier">variable</span><span class="special">)</span> <span class="special">{</span> <span class="special">\</span>
455 <span class="identifier">variable</span> <span class="special">+=</span> <span class="identifier">offset</span><span class="special">;</span> <span class="special">\</span>
456 <span class="special">};</span> <span class="special">\</span>
457 <span class="identifier">BOOST_SCOPE_EXIT_ALL_ID</span><span class="special">(</span><span class="identifier">BOOST_PP_CAT</span><span class="special">(</span><span class="identifier">dec</span><span class="special">,</span> <span class="identifier">__LINE__</span><span class="special">),</span> <span class="special">\</span>
458 <span class="special">=,</span> <span class="special">&amp;</span><span class="identifier">variable</span><span class="special">)</span> <span class="special">{</span> <span class="special">\</span>
459 <span class="identifier">variable</span> <span class="special">-=</span> <span class="identifier">offset</span><span class="special">;</span> <span class="special">\</span>
460 <span class="special">};</span>
461
462 <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>
463 <span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">delta</span><span class="special">)</span> <span class="special">{</span>
464 <span class="identifier">SCOPE_EXIT_INC_DEC_TPL</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">delta</span><span class="special">)</span> <span class="comment">// Multiple scope exits on same line.</span>
465 <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">x</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
466 <span class="special">}</span>
467
468 <span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span>
469 <span class="keyword">int</span> <span class="identifier">x</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">delta</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span>
470
471 <span class="special">{</span>
472 <span class="identifier">SCOPE_EXIT_INC_DEC</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">delta</span><span class="special">)</span> <span class="comment">// Multiple scope exits on same line.</span>
473 <span class="special">}</span>
474 <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">x</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
475
476 <span class="identifier">f</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">delta</span><span class="special">);</span>
477
478 <span class="preprocessor">#ifndef</span> <span class="identifier">BOOST_NO_CXX11_LAMBDAS</span>
479 <span class="special">{</span>
480 <span class="identifier">SCOPE_EXIT_ALL_INC_DEC</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">delta</span><span class="special">)</span> <span class="comment">// Multiple scope exits on same line.</span>
481 <span class="special">}</span>
482 <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">x</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
483 <span class="preprocessor">#endif</span> <span class="comment">// LAMBDAS</span>
484
485 <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span><span class="special">();</span>
486 <span class="special">}</span>
487 </pre>
488 <p>
489 </p>
490 <p>
491 As shown by the example above, the <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ID.html" title="Macro BOOST_SCOPE_EXIT_ID">BOOST_SCOPE_EXIT_ID</a></code>,
492 <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ID_TPL.html" title="Macro BOOST_SCOPE_EXIT_ID_TPL">BOOST_SCOPE_EXIT_ID_TPL</a></code>,
493 <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_END_ID.html" title="Macro BOOST_SCOPE_EXIT_END_ID">BOOST_SCOPE_EXIT_END_ID</a></code>,
494 and <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ALL_ID.html" title="Macro BOOST_SCOPE_EXIT_ALL_ID">BOOST_SCOPE_EXIT_ALL_ID</a></code>
495 macros are especially useful when it is necessary to invoke them multiple
496 times within user-defined macros (because the C++ preprocessor expands all
497 nested macros on the same line).
498 </p>
499 </div>
500 <div class="footnotes">
501 <br><hr style="width:100; text-align:left;margin-left: 0">
502 <div id="ftn.scope_exit.tutorial.capturing_no_variable.f0" class="footnote"><p><a href="#scope_exit.tutorial.capturing_no_variable.f0" class="para"><sup class="para">[3] </sup></a>
503 <span class="bold"><strong>Rationale.</strong></span> Unfortunately, it is not possible
504 to simply invoke the <a class="link" href="../index.html" title="Chapter&#160;1.&#160;Boost.ScopeExit 1.1.0">Boost.ScopeExit</a>
505 macro with no parameters as in <code class="computeroutput"><span class="identifier">BOOST_SCOPE_EXIT</span><span class="special">()</span></code> because the C++ preprocessor cannot detect
506 emptiness of a macro parameter when the parameter can start with a non-alphanumeric
507 symbol (which is the case when capturing a variable by reference <code class="computeroutput"><span class="special">&amp;</span><span class="identifier">variable</span></code>).
508 </p></div>
509 <div id="ftn.scope_exit.tutorial.capturing_all_variables__c__11_only_.f0" class="footnote"><p><a href="#scope_exit.tutorial.capturing_all_variables__c__11_only_.f0" class="para"><sup class="para">[4] </sup></a>
510 <span class="bold"><strong>Rationale.</strong></span> The <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ALL.html" title="Macro BOOST_SCOPE_EXIT_ALL">BOOST_SCOPE_EXIT_ALL</a></code>
511 macro is only defined on C++11 compilers for which the <a href="http://www.boost.org/libs/config" target="_top">Boost.Config</a>
512 macro <code class="computeroutput"><span class="identifier">BOOST_NO_CXX11_LAMBDAS</span></code>
513 is not defined. Using <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ALL.html" title="Macro BOOST_SCOPE_EXIT_ALL">BOOST_SCOPE_EXIT_ALL</a></code>
514 on C++03 compilers for which <code class="computeroutput"><span class="identifier">BOOST_NO_CXX11_LAMBDAS</span></code>
515 is defined will generate (possibly cryptic) compiler errors. Note that
516 a new macro <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ALL.html" title="Macro BOOST_SCOPE_EXIT_ALL">BOOST_SCOPE_EXIT_ALL</a></code>
517 needed to be introduced instead of reusing <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT.html" title="Macro BOOST_SCOPE_EXIT">BOOST_SCOPE_EXIT</a></code>
518 because <code class="computeroutput"><span class="identifier">BOOST_SCOPE_EXIT</span><span class="special">(&amp;)</span></code> and <code class="computeroutput"><span class="identifier">BOOST_SCOPE_EXIT</span><span class="special">(=)</span></code> cannot be distinguished from <code class="computeroutput"><span class="identifier">BOOST_SCOPE_EXIT</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span></code> or
519 <code class="computeroutput"><span class="identifier">BOOST_SCOPE_EXIT</span><span class="special">(</span><span class="identifier">this_</span><span class="special">)</span></code>
520 using the C++ preprocessor given that the symbols <code class="computeroutput"><span class="special">&amp;</span></code>
521 and <code class="computeroutput"><span class="special">=</span></code> are neither prefxied
522 nor postfixed by alphanumeric tokens (this is not an issue for <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ALL.html" title="Macro BOOST_SCOPE_EXIT_ALL">BOOST_SCOPE_EXIT_ALL</a></code> which always
523 has the non-alphanumeric <code class="computeroutput"><span class="special">&amp;</span></code>
524 or <code class="computeroutput"><span class="special">=</span></code> as the first capture
525 so the first capture tokens are simply never compared with neither <code class="computeroutput"><span class="keyword">void</span></code> nor <code class="computeroutput"><span class="identifier">this_</span></code>
526 for this macro).
527 </p></div>
528 <div id="ftn.scope_exit.tutorial.capturing_all_variables__c__11_only_.f1" class="footnote"><p><a href="#scope_exit.tutorial.capturing_all_variables__c__11_only_.f1" class="para"><sup class="para">[5] </sup></a>
529 At present, there seems to be some discussion to allow C++11 lambda
530 functions to capture data members without capturing the object <code class="computeroutput"><span class="keyword">this</span></code>. If the C++11 standard were changed
531 to allow this, the <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ALL.html" title="Macro BOOST_SCOPE_EXIT_ALL">BOOST_SCOPE_EXIT_ALL</a></code>
532 macro syntax could be extended to be a superset of the <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT.html" title="Macro BOOST_SCOPE_EXIT">BOOST_SCOPE_EXIT</a></code>
533 macro while keeping full backward compatibility.
534 </p></div>
535 <div id="ftn.scope_exit.tutorial.capturing_all_variables__c__11_only_.f2" class="footnote"><p><a href="#scope_exit.tutorial.capturing_all_variables__c__11_only_.f2" class="para"><sup class="para">[6] </sup></a>
536 On compilers that support the use of the <code class="computeroutput"><span class="keyword">typename</span></code>
537 outside templates as allowed by the C++11 standard, <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ALL.html" title="Macro BOOST_SCOPE_EXIT_ALL">BOOST_SCOPE_EXIT_ALL</a></code>
538 can use both <code class="computeroutput"><span class="keyword">this</span></code> and
539 <code class="computeroutput"><span class="identifier">this_</span></code> to capture the
540 object in scope (notably, this is not the case for the MSVC 10.0 compiler).
541 </p></div>
542 <div id="ftn.scope_exit.tutorial.template_workaround__gcc_.f0" class="footnote"><p><a href="#scope_exit.tutorial.template_workaround__gcc_.f0" class="para"><sup class="para">[7] </sup></a>
543 <span class="bold"><strong>Rationale.</strong></span> GCC versions compliant with
544 C++11 do not present this issue and given that <code class="computeroutput"><a class="link" href="../BOOST_SCOPE_EXIT_ALL.html" title="Macro BOOST_SCOPE_EXIT_ALL">BOOST_SCOPE_EXIT_ALL</a></code>
545 is only available on C++11 compilers, there is no need for a <code class="computeroutput"><span class="identifier">BOOST_SCOPE_EXIT_ALL_TPL</span></code> macro.
546 </p></div>
547 <div id="ftn.scope_exit.tutorial.same_line_expansions.f0" class="footnote"><p><a href="#scope_exit.tutorial.same_line_expansions.f0" class="para"><sup class="para">[8] </sup></a>
548 <span class="bold"><strong>Rationale.</strong></span> The library macros internally
549 use <code class="computeroutput"><span class="identifier">__LINE__</span></code> to generate
550 unique identifiers. Therefore, if the same macro is expanded more than
551 on time on the same line, the generated identifiers will no longer be unique
552 and the code will not compile. (This restriction does not apply to MSVC
553 and other compilers that provide the non-standard <code class="computeroutput"><span class="identifier">__COUNTER__</span></code>
554 macro.)
555 </p></div>
556 <div id="ftn.scope_exit.tutorial.same_line_expansions.f1" class="footnote"><p><a href="#scope_exit.tutorial.same_line_expansions.f1" class="para"><sup class="para">[9] </sup></a>
557 Because there are restrictions on the set of tokens that the C++ preprocessor
558 can concatenate and because not all compilers correctly implement these
559 restrictions, it is in general recommended to specify unique identifiers
560 as a combination of alphanumeric tokens.
561 </p></div>
562 </div>
563 </div>
564 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
565 <td align="left"></td>
566 <td align="right"><div class="copyright-footer">Copyright &#169; 2006-2012 Alexander Nasonov, Lorenzo Caminiti<p>
567 Distributed under the Boost Software License, Version 1.0 (see accompanying
568 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>)
569 </p>
570 </div></td>
571 </tr></table>
572 <hr>
573 <div class="spirit-nav">
574 <a accesskey="p" href="getting_started.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="alternatives.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
575 </div>
576 </body>
577 </html>