1 | <?xml version="1.0" encoding="utf-8" ?> |
---|
2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
---|
3 | <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
---|
4 | <head> |
---|
5 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
---|
6 | <meta name="generator" content="Docutils 0.3.8: http://docutils.sourceforge.net/" /> |
---|
7 | <title>The Boost Parameter Library</title> |
---|
8 | <link rel="stylesheet" href="rst.css" type="text/css" /> |
---|
9 | </head> |
---|
10 | <body> |
---|
11 | <div class="document" id="the-boost-parameter-library"> |
---|
12 | <h1 class="title">The Boost Parameter Library</h1> |
---|
13 | <p><a class="reference" href="../../../../index.htm"><img alt="Boost" src="../../../../boost.png" /></a></p> |
---|
14 | <hr class="docutils" /> |
---|
15 | <table class="docutils field-list" frame="void" rules="none"> |
---|
16 | <col class="field-name" /> |
---|
17 | <col class="field-body" /> |
---|
18 | <tbody valign="top"> |
---|
19 | <tr class="field"><th class="field-name">Abstract:</th><td class="field-body"><p class="first">Use this library to write functions that accept |
---|
20 | arguments by name:</p> |
---|
21 | <pre class="literal-block"> |
---|
22 | new_window("alert", <strong>width=10</strong>, <strong>titlebar=false</strong>); |
---|
23 | </pre> |
---|
24 | <p class="last">Since named arguments can be passed in any order, they are |
---|
25 | especially useful when a function has more than one parameter |
---|
26 | with a useful default value.</p> |
---|
27 | </td> |
---|
28 | </tr> |
---|
29 | </tbody> |
---|
30 | </table> |
---|
31 | <hr class="docutils" /> |
---|
32 | <table class="docutils field-list" frame="void" rules="none"> |
---|
33 | <col class="field-name" /> |
---|
34 | <col class="field-body" /> |
---|
35 | <tbody valign="top"> |
---|
36 | <tr class="field"><th class="field-name">Authors:</th><td class="field-body">David Abrahams, Daniel Wallin</td> |
---|
37 | </tr> |
---|
38 | <tr class="field"><th class="field-name">Contact:</th><td class="field-body"><a class="reference" href="mailto:dave@boost-consulting.com">dave@boost-consulting.com</a>, <a class="reference" href="mailto:dalwan01@student.umu.se">dalwan01@student.umu.se</a></td> |
---|
39 | </tr> |
---|
40 | <tr class="field"><th class="field-name">Organization:</th><td class="field-body"><a class="reference" href="http://www.boost-consulting.com">Boost Consulting</a></td> |
---|
41 | </tr> |
---|
42 | <tr class="field"><th class="field-name">Date:</th><td class="field-body">$Date: 2005/07/18 20:34:31 $</td> |
---|
43 | </tr> |
---|
44 | <tr class="field"><th class="field-name">Copyright:</th><td class="field-body">Copyright David Abrahams, Daniel Wallin |
---|
45 | 2005. Distributed under the Boost Software License, |
---|
46 | Version 1.0. (See accompanying file LICENSE_1_0.txt |
---|
47 | or copy at <a class="reference" href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</td> |
---|
48 | </tr> |
---|
49 | </tbody> |
---|
50 | </table> |
---|
51 | <hr class="docutils" /> |
---|
52 | <div class="contents topic" id="table-of-contents"> |
---|
53 | <p class="topic-title first"><a name="table-of-contents"><strong>Table of Contents</strong></a></p> |
---|
54 | <ul class="auto-toc simple"> |
---|
55 | <li><a class="reference" href="#introduction" id="id20" name="id20">1 Introduction</a></li> |
---|
56 | <li><a class="reference" href="#tutorial" id="id21" name="id21">2 Tutorial</a><ul class="auto-toc"> |
---|
57 | <li><a class="reference" href="#headers-and-namespaces" id="id22" name="id22">2.1 Headers And Namespaces</a></li> |
---|
58 | <li><a class="reference" href="#the-abstract-interface-to-dfs" id="id23" name="id23">2.2 The Abstract Interface to <tt class="docutils literal"><span class="pre">depth_first_search</span></tt></a></li> |
---|
59 | <li><a class="reference" href="#defining-the-keywords" id="id24" name="id24">2.3 Defining the Keywords</a></li> |
---|
60 | <li><a class="reference" href="#defining-the-implementation-function" id="id25" name="id25">2.4 Defining the Implementation Function</a></li> |
---|
61 | <li><a class="reference" href="#adding-defaults" id="id26" name="id26">2.5 Adding Defaults</a><ul class="auto-toc"> |
---|
62 | <li><a class="reference" href="#syntax" id="id27" name="id27">2.5.1 Syntax</a></li> |
---|
63 | <li><a class="reference" href="#getting-more-realistic" id="id28" name="id28">2.5.2 Getting More Realistic</a></li> |
---|
64 | <li><a class="reference" href="#the-binding-metafunction" id="id29" name="id29">2.5.3 The <tt class="docutils literal"><span class="pre">binding</span></tt> <span class="concept">Metafunction</span></a></li> |
---|
65 | <li><a class="reference" href="#beyond-ordinary-default-arguments" id="id30" name="id30">2.5.4 Beyond Ordinary Default Arguments</a></li> |
---|
66 | </ul> |
---|
67 | </li> |
---|
68 | <li><a class="reference" href="#syntactic-refinement" id="id31" name="id31">2.6 Syntactic Refinement</a><ul class="auto-toc"> |
---|
69 | <li><a class="reference" href="#describing-the-positional-argument-order" id="id32" name="id32">2.6.1 Describing the Positional Argument Order</a></li> |
---|
70 | <li><a class="reference" href="#forwarding-functions" id="id33" name="id33">2.6.2 Forwarding Functions</a></li> |
---|
71 | <li><a class="reference" href="#out-parameters" id="id34" name="id34">2.6.3 “Out” Parameters</a></li> |
---|
72 | <li><a class="reference" href="#generating-forwarding-functions-with-macros" id="id35" name="id35">2.6.4 Generating Forwarding Functions with Macros</a></li> |
---|
73 | </ul> |
---|
74 | </li> |
---|
75 | <li><a class="reference" href="#controlling-overload-resolution" id="id36" name="id36">2.7 Controlling Overload Resolution</a><ul class="auto-toc"> |
---|
76 | <li><a class="reference" href="#updating-the-parameterspec" id="id37" name="id37">2.7.1 Updating the <span class="concept">ParameterSpec</span></a></li> |
---|
77 | <li><a class="reference" href="#applying-sfinae-to-the-overload-set" id="id38" name="id38">2.7.2 Applying SFINAE to the Overload Set</a></li> |
---|
78 | <li><a class="reference" href="#reducing-boilerplate-with-macros" id="id39" name="id39">2.7.3 Reducing Boilerplate With Macros</a></li> |
---|
79 | </ul> |
---|
80 | </li> |
---|
81 | <li><a class="reference" href="#efficiency-issues" id="id40" name="id40">2.8 Efficiency Issues</a><ul class="auto-toc"> |
---|
82 | <li><a class="reference" href="#eliminating-copies" id="id41" name="id41">2.8.1 Eliminating Copies</a></li> |
---|
83 | <li><a class="reference" href="#lazy-default-computation" id="id42" name="id42">2.8.2 Lazy Default Computation</a></li> |
---|
84 | <li><a class="reference" href="#default-forwarding" id="id43" name="id43">2.8.3 Default Forwarding</a></li> |
---|
85 | <li><a class="reference" href="#dispatching-based-on-the-presence-of-a-default" id="id44" name="id44">2.8.4 Dispatching Based on the Presence of a Default</a></li> |
---|
86 | </ul> |
---|
87 | </li> |
---|
88 | </ul> |
---|
89 | </li> |
---|
90 | <li><a class="reference" href="#portability-considerations" id="id45" name="id45">3 Portability Considerations</a><ul class="auto-toc"> |
---|
91 | <li><a class="reference" href="#no-sfinae-support" id="id46" name="id46">3.1 No SFINAE Support</a></li> |
---|
92 | <li><a class="reference" href="#no-support-for-result-of" id="id47" name="id47">3.2 No Support for <tt class="docutils literal"><span class="pre">result_of</span></tt></a></li> |
---|
93 | <li><a class="reference" href="#can-t-declare-parameterspec-via-typedef" id="id48" name="id48">3.3 Can't Declare <span class="concept">ParameterSpec</span> via <tt class="docutils literal"><span class="pre">typedef</span></tt></a></li> |
---|
94 | <li><a class="reference" href="#default-arguments-unsupported-on-nested-templates" id="id49" name="id49">3.4 Default Arguments Unsupported on Nested Templates</a></li> |
---|
95 | <li><a class="reference" href="#compiler-can-t-see-references-in-unnamed-namespace" id="id50" name="id50">3.5 Compiler Can't See References In Unnamed Namespace</a></li> |
---|
96 | </ul> |
---|
97 | </li> |
---|
98 | <li><a class="reference" href="#reference" id="id51" name="id51">4 Reference</a></li> |
---|
99 | <li><a class="reference" href="#acknowledgements" id="id52" name="id52">5 Acknowledgements</a></li> |
---|
100 | </ul> |
---|
101 | </div> |
---|
102 | <hr class="docutils" /> |
---|
103 | <div class="section" id="introduction"> |
---|
104 | <h1><a class="toc-backref" href="#id20" name="introduction">1 Introduction</a></h1> |
---|
105 | <p>In C++, arguments are normally given meaning by their positions |
---|
106 | with respect to a parameter list. That protocol is fine when there |
---|
107 | is at most one parameter with a default value, but when there are |
---|
108 | even a few useful defaults, the positional interface becomes |
---|
109 | burdensome:</p> |
---|
110 | <ul> |
---|
111 | <li><p class="first">Since an argument's meaning is given by its position, we have to |
---|
112 | choose an (often arbitrary) order for parameters with default |
---|
113 | values, making some combinations of defaults unusable:</p> |
---|
114 | <pre class="literal-block"> |
---|
115 | window* new_window( |
---|
116 | char const* name, |
---|
117 | <strong>int border_width = default_border_width,</strong> |
---|
118 | bool movable = true, |
---|
119 | bool initially_visible = true |
---|
120 | ); |
---|
121 | |
---|
122 | const bool movability = false; |
---|
123 | window* w = new_window("alert box", movability); |
---|
124 | </pre> |
---|
125 | <p>In the example above we wanted to make an unmoveable window |
---|
126 | with a default <tt class="docutils literal"><span class="pre">border_width</span></tt>, but instead we got a moveable |
---|
127 | window with a <tt class="docutils literal"><span class="pre">border_width</span></tt> of zero. To get the desired |
---|
128 | effect, we'd need to write:</p> |
---|
129 | <pre class="literal-block"> |
---|
130 | window* w = new_window( |
---|
131 | "alert box", <strong>default_border_width</strong>, movability); |
---|
132 | </pre> |
---|
133 | </li> |
---|
134 | <li><p class="first">It can become difficult for readers to understand the meaning of |
---|
135 | arguments at the call site:</p> |
---|
136 | <pre class="literal-block"> |
---|
137 | window* w = new_window("alert", 1, true, false); |
---|
138 | </pre> |
---|
139 | <p>Is this window moveable and initially invisible, or unmoveable |
---|
140 | and initially visible? The reader needs to remember the order |
---|
141 | of arguments to be sure.</p> |
---|
142 | </li> |
---|
143 | <li><p class="first">The author of the call may not remember the order of the |
---|
144 | arguments either, leading to hard-to-find bugs.</p> |
---|
145 | </li> |
---|
146 | </ul> |
---|
147 | <p>This library addresses the problems outlined above by associating |
---|
148 | each parameter with a keyword object. Now users can identify |
---|
149 | arguments by keyword, rather than by position:</p> |
---|
150 | <pre class="literal-block"> |
---|
151 | window* w = new_window("alert box", <strong>movable=</strong>false); // OK! |
---|
152 | </pre> |
---|
153 | <!-- I'm inclined to leave this part out. In particular, the 2nd |
---|
154 | point is kinda lame because even with the library, we need to |
---|
155 | introduce overloads - - dwa: |
---|
156 | |
---|
157 | C++ has two other limitations, with respect to default arguments, |
---|
158 | that are unrelated to its positional interface: |
---|
159 | |
---|
160 | * Default values cannot depend on the values of other function |
---|
161 | parameters: |
---|
162 | |
---|
163 | .. parsed-literal:: |
---|
164 | |
---|
165 | // Can we make resize windows to a square shape by default? |
---|
166 | void resize( |
---|
167 | window* w, |
---|
168 | int **width**, |
---|
169 | int height **= width** // nope, error! |
---|
170 | ); |
---|
171 | |
---|
172 | * Default values in function templates are useless for any |
---|
173 | argument whose type should be deduced when the argument is |
---|
174 | supplied explicitly:: |
---|
175 | |
---|
176 | template <class T> |
---|
177 | void f(T x = 0); |
---|
178 | |
---|
179 | f(3.14) // ok: x supplied explicitly; T is double |
---|
180 | f(); // error: can't deduce T from default argument 0! |
---|
181 | |
---|
182 | As a side effect of using the Boost Parameter library, you may find |
---|
183 | that you circumvent both of these limitations quite naturally. --> |
---|
184 | </div> |
---|
185 | <div class="section" id="tutorial"> |
---|
186 | <h1><a class="toc-backref" href="#id21" name="tutorial">2 Tutorial</a></h1> |
---|
187 | <p>In this section we'll show how the Parameter library can be used to |
---|
188 | build an expressive interface to the <a class="reference" href="../../../graph/index.html">Boost Graph library</a>'s |
---|
189 | <a class="reference" href="../../../graph/doc/depth_first_search.html"><tt class="docutils literal"><span class="pre">depth_first_search</span></tt></a> algorithm.<a class="footnote-reference" href="#old-interface" id="id2" name="id2"><sup>1</sup></a> After laying some groundwork |
---|
190 | and describing the algorithm's abstract interface, we'll show you |
---|
191 | how to build a basic implementation with keyword support. Then |
---|
192 | we'll add support for default arguments and we'll gradually refine the |
---|
193 | implementation with syntax improvements. Finally we'll show how to |
---|
194 | streamline the implementation of named parameter interfaces, |
---|
195 | improve their participation in overload resolution, and optimize |
---|
196 | their runtime efficiency.</p> |
---|
197 | <div class="section" id="headers-and-namespaces"> |
---|
198 | <h2><a class="toc-backref" href="#id22" name="headers-and-namespaces">2.1 Headers And Namespaces</a></h2> |
---|
199 | <p>Most components of the Parameter library are declared in a |
---|
200 | header named for the component. For example,</p> |
---|
201 | <pre class="literal-block"> |
---|
202 | #include <boost/parameter/keyword.hpp> |
---|
203 | </pre> |
---|
204 | <p>will ensure <tt class="docutils literal"><span class="pre">boost::parameter::keyword</span></tt> is known to the |
---|
205 | compiler. There is also a combined header, |
---|
206 | <tt class="docutils literal"><span class="pre">boost/parameter.hpp</span></tt>, that includes most of the library's |
---|
207 | components. For the the rest of this tutorial, unless we say |
---|
208 | otherwise, you can use the rule above to figure out which header |
---|
209 | to <tt class="docutils literal"><span class="pre">#include</span></tt> to access any given component of the library.</p> |
---|
210 | <p>Also, the examples below will also be written as if the |
---|
211 | namespace alias</p> |
---|
212 | <pre class="literal-block"> |
---|
213 | namespace parameter = boost::parameter; |
---|
214 | </pre> |
---|
215 | <p>has been declared: we'll write <tt class="docutils literal"><span class="pre">parameter::xxx</span></tt> instead of |
---|
216 | <tt class="docutils literal"><span class="pre">boost::parameter::xxx</span></tt>.</p> |
---|
217 | </div> |
---|
218 | <div class="section" id="the-abstract-interface-to-dfs"> |
---|
219 | <h2><a class="toc-backref" href="#id23" name="the-abstract-interface-to-dfs">2.2 The Abstract Interface to <tt class="docutils literal"><span class="pre">depth_first_search</span></tt></a></h2> |
---|
220 | <p>The Graph library's <tt class="docutils literal"><span class="pre">depth_first_search</span></tt> algorithm is a generic function accepting |
---|
221 | from one to four arguments by reference. If all arguments were |
---|
222 | required, its signature might be as follows:</p> |
---|
223 | <pre class="literal-block"> |
---|
224 | template < |
---|
225 | class Graph, class DFSVisitor, class Index, class ColorMap |
---|
226 | > |
---|
227 | void depth_first_search( |
---|
228 | , Graph const& graph |
---|
229 | , DFSVisitor visitor |
---|
230 | , typename graph_traits<g>::vertex_descriptor root_vertex |
---|
231 | , IndexMap index_map |
---|
232 | , ColorMap& color); |
---|
233 | </pre> |
---|
234 | <p>However, most of the parameters have a useful default value, as |
---|
235 | shown in the table below.</p> |
---|
236 | <span class="target" id="parameter-table"></span><span class="target" id="default-expressions"></span><table border="1" class="docutils"> |
---|
237 | <caption><tt class="docutils literal"><span class="pre">depth_first_search</span></tt> Parameters</caption> |
---|
238 | <colgroup> |
---|
239 | <col width="27%" /> |
---|
240 | <col width="17%" /> |
---|
241 | <col width="57%" /> |
---|
242 | </colgroup> |
---|
243 | <thead valign="bottom"> |
---|
244 | <tr><th>Parameter Name</th> |
---|
245 | <th>Dataflow</th> |
---|
246 | <th>Default Value (if any)</th> |
---|
247 | </tr> |
---|
248 | </thead> |
---|
249 | <tbody valign="top"> |
---|
250 | <tr><td><tt class="docutils literal"><span class="pre">graph</span></tt></td> |
---|
251 | <td>in</td> |
---|
252 | <td>none - this argument is required.</td> |
---|
253 | </tr> |
---|
254 | <tr><td><tt class="docutils literal"><span class="pre">visitor</span></tt></td> |
---|
255 | <td>in</td> |
---|
256 | <td><tt class="docutils literal"><span class="pre">boost::dfs_visitor<>()</span></tt></td> |
---|
257 | </tr> |
---|
258 | <tr><td><tt class="docutils literal"><span class="pre">root_vertex</span></tt></td> |
---|
259 | <td>in</td> |
---|
260 | <td><tt class="docutils literal"><span class="pre">*vertices(graph).first</span></tt></td> |
---|
261 | </tr> |
---|
262 | <tr><td><tt class="docutils literal"><span class="pre">index_map</span></tt></td> |
---|
263 | <td>in</td> |
---|
264 | <td><tt class="docutils literal"><span class="pre">get(boost::vertex_index,graph)</span></tt></td> |
---|
265 | </tr> |
---|
266 | <tr><td><tt class="docutils literal"><span class="pre">color_map</span></tt></td> |
---|
267 | <td>out</td> |
---|
268 | <td>an <tt class="docutils literal"><span class="pre">iterator_property_map</span></tt> |
---|
269 | created from a <tt class="docutils literal"><span class="pre">std::vector</span></tt> of |
---|
270 | <tt class="docutils literal"><span class="pre">default_color_type</span></tt> of size |
---|
271 | <tt class="docutils literal"><span class="pre">num_vertices(graph)</span></tt> and using |
---|
272 | <tt class="docutils literal"><span class="pre">index_map</span></tt> for the index map.</td> |
---|
273 | </tr> |
---|
274 | </tbody> |
---|
275 | </table> |
---|
276 | <p>Don't be intimidated by the complex default values. For the |
---|
277 | purposes of this exercise, you don't need to understand what they |
---|
278 | mean. Also, we'll show you how the default for <tt class="docutils literal"><span class="pre">color_map</span></tt> is |
---|
279 | computed later in the tutorial; trust us when we say that the |
---|
280 | complexity of its default will become valuable.</p> |
---|
281 | </div> |
---|
282 | <div class="section" id="defining-the-keywords"> |
---|
283 | <h2><a class="toc-backref" href="#id24" name="defining-the-keywords">2.3 Defining the Keywords</a></h2> |
---|
284 | <p>The point of this exercise is to make it possible to call |
---|
285 | <tt class="docutils literal"><span class="pre">depth_first_search</span></tt> with keyword arguments, leaving out any |
---|
286 | arguments for which the default is appropriate:</p> |
---|
287 | <pre class="literal-block"> |
---|
288 | graphs::depth_first_search(g, <strong>color_map = my_color_map</strong>); |
---|
289 | </pre> |
---|
290 | <p>To make that syntax legal, there needs to be an object called |
---|
291 | <tt class="docutils literal"><span class="pre">color_map</span></tt> with an assignment operator that can accept a |
---|
292 | <tt class="docutils literal"><span class="pre">my_color_map</span></tt> argument. In this step we'll create one such |
---|
293 | <strong>keyword object</strong> for each parameter. Each keyword object will be |
---|
294 | identified by a unique <strong>keyword tag type</strong>.</p> |
---|
295 | <p>We're going to define our interface in namespace <tt class="docutils literal"><span class="pre">graphs</span></tt>. Since |
---|
296 | users need access to the keyword objects, but not the tag types, |
---|
297 | we'll define the keyword objects so they're acceessible through |
---|
298 | <tt class="docutils literal"><span class="pre">graphs</span></tt>, and we'll hide the tag types away in a tested |
---|
299 | namespace, <tt class="docutils literal"><span class="pre">graphs::tag</span></tt>. The library provides a convenient |
---|
300 | macro for that purpose (MSVC6.x users see this <a class="reference" href="#compiler-can-t-see-references-in-unnamed-namespace">note</a>):</p> |
---|
301 | <pre class="literal-block"> |
---|
302 | #include <boost/parameter/keyword.hpp> |
---|
303 | |
---|
304 | namespace graphs |
---|
305 | { |
---|
306 | BOOST_PARAMETER_KEYWORD(tag, graph) // Note: no semicolon |
---|
307 | BOOST_PARAMETER_KEYWORD(tag, visitor) |
---|
308 | BOOST_PARAMETER_KEYWORD(tag, root_vertex) |
---|
309 | BOOST_PARAMETER_KEYWORD(tag, index_map) |
---|
310 | BOOST_PARAMETER_KEYWORD(tag, color_map) |
---|
311 | } |
---|
312 | </pre> |
---|
313 | <p>The declaration of the <tt class="docutils literal"><span class="pre">visitor</span></tt> keyword you see here is |
---|
314 | equivalent to:</p> |
---|
315 | <pre class="literal-block"> |
---|
316 | namespace graphs |
---|
317 | { |
---|
318 | namespace tag { struct visitor; } |
---|
319 | namespace { |
---|
320 | boost::parameter::keyword<tag::visitor>& visitor |
---|
321 | = boost::parameter::keyword<tag::visitor>::get(); |
---|
322 | } |
---|
323 | } |
---|
324 | </pre> |
---|
325 | <p>This “fancy dance” involving the unnamed namespace and references |
---|
326 | is all done to avoid violating the One Definition Rule (ODR)<a class="footnote-reference" href="#odr" id="id5" name="id5"><sup>2</sup></a> when the named parameter interface is used by function |
---|
327 | templates that are instantiated in multiple translation |
---|
328 | units.</p> |
---|
329 | </div> |
---|
330 | <div class="section" id="defining-the-implementation-function"> |
---|
331 | <h2><a class="toc-backref" href="#id25" name="defining-the-implementation-function">2.4 Defining the Implementation Function</a></h2> |
---|
332 | <p>Next we can write the skeleton of the function that implements |
---|
333 | the core of <tt class="docutils literal"><span class="pre">depth_first_search</span></tt>:</p> |
---|
334 | <pre class="literal-block"> |
---|
335 | namespace graphs { namespace core |
---|
336 | { |
---|
337 | template <class ArgumentPack> |
---|
338 | void depth_first_search(ArgumentPack const& args) |
---|
339 | { |
---|
340 | // algorithm implementation goes here |
---|
341 | } |
---|
342 | }} |
---|
343 | </pre> |
---|
344 | <p><tt class="docutils literal"><span class="pre">core::depth_first_search</span></tt> has an <span class="concept">ArgumentPack</span> |
---|
345 | parameter: a bundle of references to the arguments that the caller |
---|
346 | passes to the algorithm, tagged with their keywords. To extract |
---|
347 | each parameter, just pass its keyword object to the |
---|
348 | <span class="concept">ArgumentPack</span>'s subscript operator. Just to get a feel for how |
---|
349 | things work, let's add some temporary code to print the arguments:</p> |
---|
350 | <pre class="literal-block"> |
---|
351 | namespace graphs { namespace core |
---|
352 | { |
---|
353 | template <class ArgumentPack> |
---|
354 | void depth_first_search(ArgumentPack const& args) |
---|
355 | { |
---|
356 | std::cout << "graph:\t" << <strong>args[graph]</strong> << std::endl; |
---|
357 | std::cout << "visitor:\t" << <strong>args[visitor]</strong> << std::endl; |
---|
358 | std::cout << "root_vertex:\t" << <strong>args[root_vertex]</strong> << std::endl; |
---|
359 | std::cout << "index_map:\t" << <strong>args[index_map]</strong> << std::endl; |
---|
360 | std::cout << "color_map:\t" << <strong>args[color_map]</strong> << std::endl; |
---|
361 | } |
---|
362 | }} // graphs::core |
---|
363 | </pre> |
---|
364 | <p>It's unlikely that many of the arguments the caller will eventually |
---|
365 | pass to <tt class="docutils literal"><span class="pre">depth_first_search</span></tt> can be printed, but for now the code |
---|
366 | above will give us something to experiment with. To see the |
---|
367 | keywords in action, we can write a little test driver:</p> |
---|
368 | <pre class="literal-block"> |
---|
369 | int main() |
---|
370 | { |
---|
371 | using namespace graphs; |
---|
372 | |
---|
373 | core::depth_first_search(<strong>(</strong> |
---|
374 | graph = 'G', visitor = 2, root_vertex = 3.5, |
---|
375 | index_map = "hello, world", color_map = false<strong>)</strong>); |
---|
376 | } |
---|
377 | </pre> |
---|
378 | <p>An overloaded comma operator (<tt class="docutils literal"><span class="pre">operator,</span></tt>) combines the results |
---|
379 | of assigning to each keyword object into a single <span class="concept">ArgumentPack</span> |
---|
380 | object that gets passed on to <tt class="docutils literal"><span class="pre">core::depth_first_search</span></tt>. The |
---|
381 | extra set of parentheses you see in the example above are required: |
---|
382 | without them, each assignment would be interpreted as a separate |
---|
383 | function argument and the comma operator wouldn't take effect. |
---|
384 | We'll show you how to get rid of the extra parentheses later in |
---|
385 | this tutorial.</p> |
---|
386 | <p>Of course, we can pass the arguments in any order:</p> |
---|
387 | <pre class="literal-block"> |
---|
388 | int main() |
---|
389 | { |
---|
390 | using namespace graphs; |
---|
391 | |
---|
392 | core::depth_first_search(( |
---|
393 | root_vertex = 3.5, graph = 'G', color_map = false, |
---|
394 | index_map = "hello, world", visitor = 2)); |
---|
395 | } |
---|
396 | </pre> |
---|
397 | <p>either of the two programs above will print:</p> |
---|
398 | <pre class="literal-block"> |
---|
399 | graph: G |
---|
400 | visitor: 2 |
---|
401 | root_vertex: 3.5 |
---|
402 | index_map: hello, world |
---|
403 | color_map: false |
---|
404 | </pre> |
---|
405 | </div> |
---|
406 | <div class="section" id="adding-defaults"> |
---|
407 | <h2><a class="toc-backref" href="#id26" name="adding-defaults">2.5 Adding Defaults</a></h2> |
---|
408 | <p>Currently, all the arguments to <tt class="docutils literal"><span class="pre">depth_first_search</span></tt> are |
---|
409 | required. If any parameter can't be found, there will be a |
---|
410 | compilation error where we try to extract it from the |
---|
411 | <span class="concept">ArgumentPack</span> using the subscript operator. To make it |
---|
412 | legal to omit an argument we need to give it a default value.</p> |
---|
413 | <div class="section" id="syntax"> |
---|
414 | <h3><a class="toc-backref" href="#id27" name="syntax">2.5.1 Syntax</a></h3> |
---|
415 | <p>We can make any of the parameters optional by following its keyword |
---|
416 | with the <tt class="docutils literal"><span class="pre">|</span></tt> operator and the parameter's default value within |
---|
417 | the square brackets. In the following example, we've given |
---|
418 | <tt class="docutils literal"><span class="pre">root_vertex</span></tt> a default of <tt class="docutils literal"><span class="pre">42</span></tt> and <tt class="docutils literal"><span class="pre">color_map</span></tt> a default of |
---|
419 | <tt class="docutils literal"><span class="pre">"hello,</span> <span class="pre">world"</span></tt>.</p> |
---|
420 | <pre class="literal-block"> |
---|
421 | namespace graphs { namespace core |
---|
422 | { |
---|
423 | template <class ArgumentPack> |
---|
424 | void depth_first_search(ArgumentPack const& args) |
---|
425 | { |
---|
426 | std::cout << "graph:\t" << args[graph] << std::endl; |
---|
427 | std::cout << "visitor:\t" << args[visitor] << std::endl; |
---|
428 | std::cout << "root_vertex:\t" << args[root_vertex<strong>|42</strong>] << std::endl; |
---|
429 | std::cout << "index_map:\t" << args[index_map] << std::endl; |
---|
430 | std::cout << "color_map:\t" << args[color_map<strong>|"hello, world"</strong>] << std::endl; |
---|
431 | } |
---|
432 | }} // graphs::core |
---|
433 | </pre> |
---|
434 | <p>Now we can invoke the function without supplying <tt class="docutils literal"><span class="pre">color_map</span></tt> or |
---|
435 | <tt class="docutils literal"><span class="pre">root_vertex</span></tt>:</p> |
---|
436 | <pre class="literal-block"> |
---|
437 | core::depth_first_search(( |
---|
438 | graph = 'G', index_map = "index", visitor = 6)); |
---|
439 | </pre> |
---|
440 | <p>The call above would print:</p> |
---|
441 | <pre class="literal-block"> |
---|
442 | graph: G |
---|
443 | visitor: 6 |
---|
444 | root_vertex: 42 |
---|
445 | index_map: index |
---|
446 | color_map: hello, world |
---|
447 | </pre> |
---|
448 | <div class="important"> |
---|
449 | <p class="first admonition-title">Important</p> |
---|
450 | <p class="last">The index expression <tt class="docutils literal"><span class="pre">args[…]</span></tt> always yields a <em>reference</em> |
---|
451 | that is bound either to the actual argument passed by the caller |
---|
452 | or, if no argument is passed explicitly, to the specified |
---|
453 | default value.</p> |
---|
454 | </div> |
---|
455 | </div> |
---|
456 | <div class="section" id="getting-more-realistic"> |
---|
457 | <h3><a class="toc-backref" href="#id28" name="getting-more-realistic">2.5.2 Getting More Realistic</a></h3> |
---|
458 | <p>Now it's time to put some more realistic defaults in place. We'll |
---|
459 | have to give up our print statements—at least if we want to see the |
---|
460 | defaults work—since, the default values of these |
---|
461 | parameters generally aren't printable.</p> |
---|
462 | <p>Instead, we'll connect local variables to the arguments and use |
---|
463 | those in our algorithm:</p> |
---|
464 | <pre class="literal-block"> |
---|
465 | namespace graphs { namespace core |
---|
466 | { |
---|
467 | template <class ArgumentPack> |
---|
468 | void depth_first_search(ArgumentPack const& args) |
---|
469 | { |
---|
470 | <em>Graph</em> g = args[graph]; |
---|
471 | <em>Visitor</em> v = args[visitor|<em>default-expression</em><sub>1</sub>]; |
---|
472 | <em>Vertex</em> s = args[root_vertex|<em>default-expression</em><sub>2</sub>]; |
---|
473 | <em>Index</em> i = args[index_map|<em>default-expression</em><sub>3</sub>]; |
---|
474 | <em>Color</em> c = args[visitor|<em>default-expression</em><sub>4</sub>]; |
---|
475 | |
---|
476 | <em>…use g, v, s, i, and c to implement the algorithm…</em> |
---|
477 | } |
---|
478 | }} // graphs::core |
---|
479 | </pre> |
---|
480 | <p>We'll insert the <a class="reference" href="#default-expressions">default expressions</a> in a moment, but first we |
---|
481 | need to come up with the types <em>Graph</em>, <em>Visitor</em>, <em>Vertex</em>, |
---|
482 | <em>Index</em>, and <em>Color</em>.</p> |
---|
483 | </div> |
---|
484 | <div class="section" id="the-binding-metafunction"> |
---|
485 | <h3><a name="the-binding-metafunction">2.5.3 The <tt class="docutils literal"><span class="pre">binding</span></tt> <a class="reference" href="../../../mpl/doc/refmanual/metafunction.html"><span class="concept">Metafunction</span></a></a></h3> |
---|
486 | <p>To compute the type of a parameter we can use a <a class="reference" href="../../../mpl/doc/refmanual/metafunction.html"><span class="concept">Metafunction</span></a> |
---|
487 | called <tt class="docutils literal"><span class="pre">binding</span></tt>:</p> |
---|
488 | <pre class="literal-block"> |
---|
489 | binding<ArgumentPack, Keyword, Default = void> |
---|
490 | { typedef <em>see text</em> type; }; |
---|
491 | </pre> |
---|
492 | <p>where <tt class="docutils literal"><span class="pre">Default</span></tt> is the type of the default argument, if any.</p> |
---|
493 | <p>For example, to declare and initialize <tt class="docutils literal"><span class="pre">g</span></tt> above, we could write:</p> |
---|
494 | <pre class="literal-block"> |
---|
495 | typedef typename parameter::binding< |
---|
496 | ArgumentPack,<strong>tag::graph</strong> |
---|
497 | >::type Graph; |
---|
498 | |
---|
499 | Graph g = args[graph]; |
---|
500 | </pre> |
---|
501 | <p>As shown in the <a class="reference" href="#parameter-table">parameter table</a>, <tt class="docutils literal"><span class="pre">graph</span></tt> has no default, so |
---|
502 | the <tt class="docutils literal"><span class="pre">binding</span></tt> invocation for <em>Graph</em> takes only two arguments. |
---|
503 | The default <tt class="docutils literal"><span class="pre">visitor</span></tt> is <tt class="docutils literal"><span class="pre">boost::dfs_visitor<>()</span></tt>, so the |
---|
504 | <tt class="docutils literal"><span class="pre">binding</span></tt> invocation for <em>Visitor</em> takes three arguments:</p> |
---|
505 | <pre class="literal-block"> |
---|
506 | typedef typename parameter::binding< |
---|
507 | ArgumentPack,<strong>tag::visitor,boost::dfs_visitor<></strong> |
---|
508 | >::type Visitor; |
---|
509 | |
---|
510 | Visitor v = args[visitor|<strong>boost::dfs_visitor<>()</strong>]; |
---|
511 | </pre> |
---|
512 | <p>Note that the default <tt class="docutils literal"><span class="pre">visitor</span></tt> is supplied as a <em>temporary</em> |
---|
513 | instance of <tt class="docutils literal"><span class="pre">dfs_visitor</span></tt>. Because <tt class="docutils literal"><span class="pre">args[…]</span></tt> always yields |
---|
514 | a reference, making <tt class="docutils literal"><span class="pre">v</span></tt> a reference would cause it to bind to |
---|
515 | that temporary, and immediately dangle. Therefore, it's crucial |
---|
516 | that we passed <tt class="docutils literal"><span class="pre">dfs_visitor<></span></tt>, and not <tt class="docutils literal"><span class="pre">dfs_visitor<></span> |
---|
517 | <span class="pre">const&</span></tt>, as the last argument to <tt class="docutils literal"><span class="pre">binding</span></tt>.</p> |
---|
518 | <div class="important"> |
---|
519 | <p class="first admonition-title">Important</p> |
---|
520 | <p class="last">Never pass <tt class="docutils literal"><span class="pre">binding</span></tt> a reference type as the default unless |
---|
521 | you know that the default value passed to the <span class="concept">ArgumentPack</span>'s |
---|
522 | indexing operator will outlive the reference you'll bind to it.</p> |
---|
523 | </div> |
---|
524 | <p>Sometimes there's no need to use <tt class="docutils literal"><span class="pre">binding</span></tt> at all. The |
---|
525 | <tt class="docutils literal"><span class="pre">root_vertex</span></tt> argument is required to be of the graph's |
---|
526 | <tt class="docutils literal"><span class="pre">vertex_descriptor</span></tt> type,<a class="footnote-reference" href="#vertex-descriptor" id="id6" name="id6"><sup>3</sup></a> so we can just |
---|
527 | use that knowledge to bypass <tt class="docutils literal"><span class="pre">binding</span></tt> altogether.</p> |
---|
528 | <pre class="literal-block"> |
---|
529 | typename <strong>boost::graph_traits<Graph>::vertex_descriptor</strong> |
---|
530 | s = args[root_vertex|<strong>*vertices(g).first</strong>]; |
---|
531 | </pre> |
---|
532 | <span class="target" id="dangling"></span></div> |
---|
533 | <div class="section" id="beyond-ordinary-default-arguments"> |
---|
534 | <h3><a class="toc-backref" href="#id30" name="beyond-ordinary-default-arguments">2.5.4 Beyond Ordinary Default Arguments</a></h3> |
---|
535 | <p>Here's how you might write the declaration for the <tt class="docutils literal"><span class="pre">index_map</span></tt> |
---|
536 | parameter:</p> |
---|
537 | <pre class="literal-block"> |
---|
538 | typedef typename parameter::binding< |
---|
539 | ArgumentPack |
---|
540 | , tag::index_map |
---|
541 | , <strong>typename boost::property_map<Graph, vertex_index_t>::const_type</strong> |
---|
542 | >::type Index; |
---|
543 | |
---|
544 | Index i = args[index_map|<strong>get(boost::vertex_index,g)</strong>]; |
---|
545 | </pre> |
---|
546 | <p>Notice two capabilities we've gained over what |
---|
547 | plain C++ default arguments provide:</p> |
---|
548 | <ol class="arabic"> |
---|
549 | <li><p class="first">The default value of the <tt class="docutils literal"><span class="pre">index</span></tt> parameter depends on the |
---|
550 | value of the <tt class="docutils literal"><span class="pre">graph</span></tt> parameter. That's illegal in plain C++:</p> |
---|
551 | <pre class="literal-block"> |
---|
552 | void f(int <strong>graph</strong>, int index = <strong>graph</strong> + 1); // error |
---|
553 | </pre> |
---|
554 | </li> |
---|
555 | <li><p class="first">The <tt class="docutils literal"><span class="pre">index</span></tt> parameter has a useful default, yet it is |
---|
556 | templated and its type can be deduced when an <tt class="docutils literal"><span class="pre">index</span></tt> |
---|
557 | argument is explicitly specified by the caller. In plain C++, you |
---|
558 | can <em>specify</em> a default value for a parameter with deduced type, |
---|
559 | but it's not very useful:</p> |
---|
560 | <pre class="literal-block"> |
---|
561 | template <class Index> |
---|
562 | int f(Index index <strong>= 42</strong>); // OK |
---|
563 | int y = f(); // <strong>error; can't deduce Index</strong> |
---|
564 | </pre> |
---|
565 | </li> |
---|
566 | </ol> |
---|
567 | </div> |
---|
568 | </div> |
---|
569 | <div class="section" id="syntactic-refinement"> |
---|
570 | <h2><a class="toc-backref" href="#id31" name="syntactic-refinement">2.6 Syntactic Refinement</a></h2> |
---|
571 | <p>In this section we'll describe how you can allow callers to invoke |
---|
572 | <tt class="docutils literal"><span class="pre">depth_first_search</span></tt> with just one pair of parentheses, and to |
---|
573 | omit keywords where appropriate.</p> |
---|
574 | <div class="section" id="describing-the-positional-argument-order"> |
---|
575 | <h3><a class="toc-backref" href="#id32" name="describing-the-positional-argument-order">2.6.1 Describing the Positional Argument Order</a></h3> |
---|
576 | <span class="target" id="parameterspec"></span><p>First, we'll need to build a type that describes the allowed |
---|
577 | parameters and their ordering when passed positionally. This type |
---|
578 | is known as a <span class="concept">ParameterSpec</span> (MSVC6.x users see this <a class="reference" href="#can-t-declare-parameterspec-via-typedef">note</a>):</p> |
---|
579 | <pre class="literal-block"> |
---|
580 | namespace graphs |
---|
581 | { |
---|
582 | typedef parameter::parameters< |
---|
583 | tag::graph |
---|
584 | , tag::visitor |
---|
585 | , tag::root_vertex |
---|
586 | , tag::index_map |
---|
587 | , tag::color_map |
---|
588 | > dfs_params; |
---|
589 | } |
---|
590 | </pre> |
---|
591 | <p>The <tt class="docutils literal"><span class="pre">parameters</span></tt> template supplies a function-call |
---|
592 | operator that groups all its arguments into an <span class="concept">ArgumentPack</span>. Any |
---|
593 | arguments passed to it without a keyword label will be associated |
---|
594 | with a parameter according to its position in the <span class="concept">ParameterSpec</span>. |
---|
595 | So for example, given an object <tt class="docutils literal"><span class="pre">p</span></tt> of type <tt class="docutils literal"><span class="pre">dfs_params</span></tt>,</p> |
---|
596 | <pre class="literal-block"> |
---|
597 | p('G', index_map=1) |
---|
598 | </pre> |
---|
599 | <p>yields an <span class="concept">ArgumentPack</span> whose <tt class="docutils literal"><span class="pre">graph</span></tt> parameter has a value of |
---|
600 | <tt class="docutils literal"><span class="pre">'G'</span></tt>, and whose <tt class="docutils literal"><span class="pre">index_map</span></tt> parameter has a value of <tt class="docutils literal"><span class="pre">1</span></tt>.</p> |
---|
601 | </div> |
---|
602 | <div class="section" id="forwarding-functions"> |
---|
603 | <h3><a class="toc-backref" href="#id33" name="forwarding-functions">2.6.2 Forwarding Functions</a></h3> |
---|
604 | <p>Next we need a family of overloaded <tt class="docutils literal"><span class="pre">depth_first_search</span></tt> function |
---|
605 | templates that can be called with anywhere from one to five |
---|
606 | arguments. These <em>forwarding functions</em> will invoke an instance of |
---|
607 | <tt class="docutils literal"><span class="pre">dfs_params</span></tt> as a function object, passing their parameters |
---|
608 | to its <tt class="docutils literal"><span class="pre">operator()</span></tt> and forwarding the result on to |
---|
609 | <tt class="docutils literal"><span class="pre">core::depth_first_search</span></tt>:</p> |
---|
610 | <pre class="literal-block"> |
---|
611 | namespace graphs |
---|
612 | { |
---|
613 | template <class A0> |
---|
614 | void depth_first_search(A0 const& a0) |
---|
615 | { |
---|
616 | core::depth_first_search(dfs_params()(a0)); |
---|
617 | } |
---|
618 | |
---|
619 | template <class A0, class A1> |
---|
620 | void depth_first_search(A0 const& a0, A1 const& a1) |
---|
621 | { |
---|
622 | core::depth_first_search(dfs_params()(a0,a1)); |
---|
623 | } <span class="vellipsis"> |
---|
624 | . |
---|
625 | . |
---|
626 | . |
---|
627 | </span> |
---|
628 | template <class A0, class A1, …class A4> |
---|
629 | void depth_first_search(A0 const& a0, A1 const& a1, …A4 const& a4) |
---|
630 | { |
---|
631 | core::depth_first_search(dfs_params()(a0,a1,a2,a3,a4)); |
---|
632 | } |
---|
633 | } |
---|
634 | </pre> |
---|
635 | <p>That's it! We can now call <tt class="docutils literal"><span class="pre">graphs::depth_first_search</span></tt> with |
---|
636 | from one to five arguments passed positionally or via keyword.</p> |
---|
637 | </div> |
---|
638 | <div class="section" id="out-parameters"> |
---|
639 | <h3><a class="toc-backref" href="#id34" name="out-parameters">2.6.3 “Out” Parameters</a></h3> |
---|
640 | <p>Well, that's not <em>quite</em> it. When passing arguments by keyword, |
---|
641 | the keyword object's assignment operator yields a temporary |
---|
642 | <span class="concept">ArgumentPack</span> object. A conforming C++ compiler will refuse to |
---|
643 | bind a non-<tt class="docutils literal"><span class="pre">const</span></tt> reference to a temporary, so to support a |
---|
644 | keyword interface for all arguments, the overload set above <em>must</em> |
---|
645 | take its arguments by <tt class="docutils literal"><span class="pre">const</span></tt> reference. On the other hand—as |
---|
646 | you may recall from the <a class="reference" href="#parameter-table">parameter table</a>—<tt class="docutils literal"><span class="pre">color_map</span></tt> is an |
---|
647 | “out” parameter, so it really should be passed by <em>non-</em><tt class="docutils literal"><span class="pre">const</span></tt> |
---|
648 | reference.</p> |
---|
649 | <p>A keyword object has a pair of <tt class="docutils literal"><span class="pre">operator=</span></tt> overloads that ensure |
---|
650 | we can pass anything—temporary or not, <tt class="docutils literal"><span class="pre">const</span></tt> or not—by name, |
---|
651 | while preserving the mutability of non-temporaries:</p> |
---|
652 | <pre class="literal-block"> |
---|
653 | template <class A> // handles non-const, |
---|
654 | <span class="concept">ArgumentPack</span> operator=(A&); // non-temporary objects |
---|
655 | |
---|
656 | template <class A> // handles const objects |
---|
657 | <span class="concept">ArgumentPack</span> operator=(A const&); // and temporaries |
---|
658 | </pre> |
---|
659 | <p>However, when an “out” parameter is passed positionally, there's no |
---|
660 | keyword object involved. With our <tt class="docutils literal"><span class="pre">depth_first_search</span></tt> overload |
---|
661 | set above, the <tt class="docutils literal"><span class="pre">color_map</span></tt> will be passed by <tt class="docutils literal"><span class="pre">const</span></tt> reference, |
---|
662 | and compilation will fail when mutating operations are used on it. |
---|
663 | The simple solution is to add another overload that takes a |
---|
664 | non-<tt class="docutils literal"><span class="pre">const</span></tt> reference in the position of the “out” parameter:</p> |
---|
665 | <pre class="literal-block"> |
---|
666 | template <class A0, class A1, …class A4> |
---|
667 | void depth_first_search(A0 <strong>const&</strong> a0, A1 <strong>const&</strong> a1, …A4<strong>&</strong> a4) |
---|
668 | { |
---|
669 | core::depth_first_search(dfs_params()(a0,a1,a2,a3,a4)); |
---|
670 | } |
---|
671 | </pre> |
---|
672 | <p>That approach works nicely because there is only one “out” |
---|
673 | parameter and it is in the last position. If <tt class="docutils literal"><span class="pre">color_map</span></tt> had |
---|
674 | been the first parameter, we would have needed <em>ten</em> overloads. In |
---|
675 | the worst case—where the function has five “out” parameters—2<sup>5</sup> or 32 overloads would be required. This “<a class="reference" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm">forwarding |
---|
676 | problem</a>” is well-known to generic library authors, and the C++ |
---|
677 | standard committee is working on a <a class="reference" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1690.html">proposal</a> to address it. In |
---|
678 | the meantime, you might consider using <a class="reference" href="../../../preprocessor/index.html">Boost.Preprocessor</a> to |
---|
679 | generate the overloads you need.</p> |
---|
680 | <p>If it is impractical for you to generate or write the overloads |
---|
681 | that would be required for positional “out” arguments to be passed |
---|
682 | directly, you still have the option to ask users to pass them |
---|
683 | through <a class="reference" href="http://www.boost.org/doc/html/reference_wrapper.html"><tt class="docutils literal"><span class="pre">boost::ref</span></tt></a>, which will ensure that the algorithm implementation |
---|
684 | sees a non-<tt class="docutils literal"><span class="pre">const</span></tt> reference:</p> |
---|
685 | <pre class="literal-block"> |
---|
686 | depth_first_search(g, v, s, i, <strong>boost::ref(c)</strong>); |
---|
687 | </pre> |
---|
688 | </div> |
---|
689 | <div class="section" id="generating-forwarding-functions-with-macros"> |
---|
690 | <h3><a class="toc-backref" href="#id35" name="generating-forwarding-functions-with-macros">2.6.4 Generating Forwarding Functions with Macros</a></h3> |
---|
691 | <p>To remove some of the tedium of writing overloaded forwarding |
---|
692 | functions, the library supplies a macro, suitably located in |
---|
693 | <tt class="docutils literal"><span class="pre">boost/parameter/macros.hpp</span></tt>, that will generate free function |
---|
694 | overloads for you:</p> |
---|
695 | <pre class="literal-block"> |
---|
696 | BOOST_PARAMETER_FUN(void, depth_first_search, 1, 5, dfs_params); |
---|
697 | </pre> |
---|
698 | <p>will generate a family of five <tt class="docutils literal"><span class="pre">depth_first_search</span></tt> overloads, in |
---|
699 | the current scope, that pass their arguments through |
---|
700 | <tt class="docutils literal"><span class="pre">dfs_params</span></tt>. Instead of <tt class="docutils literal"><span class="pre">core::depth_first_search</span></tt>, these |
---|
701 | overloads will forward the <span class="concept">ArgumentPack</span> on to a function called |
---|
702 | <tt class="docutils literal"><span class="pre">depth_first_search_with_named_params</span></tt>, also in the current |
---|
703 | scope. It's up to you to implement that function. You could |
---|
704 | simply transplant the body of <tt class="docutils literal"><span class="pre">core::depth_first_search</span></tt> into |
---|
705 | <tt class="docutils literal"><span class="pre">depth_first_search_with_named_params</span></tt> if you were going to use |
---|
706 | this approach.</p> |
---|
707 | <p>Note that <tt class="docutils literal"><span class="pre">BOOST_PARAMETER_FUN</span></tt> only takes arguments by <tt class="docutils literal"><span class="pre">const</span></tt> |
---|
708 | reference, so you will have to add any additional overloads |
---|
709 | required to handle positional “out” parameters yourself. We are |
---|
710 | looking into providing a more sophisticated set of macros to |
---|
711 | address this problem and others, for an upcoming release of Boost.</p> |
---|
712 | </div> |
---|
713 | </div> |
---|
714 | <div class="section" id="controlling-overload-resolution"> |
---|
715 | <h2><a class="toc-backref" href="#id36" name="controlling-overload-resolution">2.7 Controlling Overload Resolution</a></h2> |
---|
716 | <p>The parameters of our templated forwarding functions are completely |
---|
717 | general; in fact, they're a perfect match for any argument type |
---|
718 | whatsoever. The problems with exposing such general function |
---|
719 | templates have been the subject of much discussion, especially in |
---|
720 | the presence of <a class="reference" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#225">unqualified calls</a>. Probably the safest thing |
---|
721 | to do is to isolate the forwarding functions in a namespace |
---|
722 | containing no types<a class="footnote-reference" href="#using" id="id9" name="id9"><sup>5</sup></a>, but often we'd <em>like</em> our functions |
---|
723 | to play nicely with argument-dependent lookup and other function |
---|
724 | overloads. In that case, it's neccessary to remove the functions |
---|
725 | from the overload set when the passed argument types aren't |
---|
726 | appropriate.</p> |
---|
727 | <div class="section" id="updating-the-parameterspec"> |
---|
728 | <h3><a class="toc-backref" href="#id37" name="updating-the-parameterspec">2.7.1 Updating the <span class="concept">ParameterSpec</span></a></h3> |
---|
729 | <p>This sort of overload control can be accomplished in C++ by taking |
---|
730 | advantage of the SFINAE (Substitution Failure Is Not An Error) |
---|
731 | rule.<a class="footnote-reference" href="#sfinae" id="id11" name="id11"><sup>6</sup></a> You can take advantage of the Parameter library's |
---|
732 | built-in SFINAE support by using the following class templates in |
---|
733 | your <span class="concept">ParameterSpec</span>:</p> |
---|
734 | <pre class="literal-block"> |
---|
735 | template< class KeywordTag, class Predicate = <em>unspecified</em> > |
---|
736 | struct required; |
---|
737 | |
---|
738 | template< class KeywordTag, class Predicate = <em>unspecified</em> > |
---|
739 | struct optional; |
---|
740 | </pre> |
---|
741 | <p>Instead of using keyword tags directly, we can wrap them in |
---|
742 | <tt class="docutils literal"><span class="pre">required</span></tt> and <tt class="docutils literal"><span class="pre">optional</span></tt> to indicate which function parameters |
---|
743 | are required, and optionally pass <tt class="docutils literal"><span class="pre">Predicate</span></tt>s to describe the |
---|
744 | type requirements for each function parameter. The <tt class="docutils literal"><span class="pre">Predicate</span></tt> |
---|
745 | argument must be a unary <a class="reference" href="../../../mpl/doc/refmanual/lambda-expression.html">MPL lambda expression</a> that, when |
---|
746 | applied to the actual type of the argument, indicates whether that |
---|
747 | argument type meets the function's requirements for that parameter |
---|
748 | position.</p> |
---|
749 | <p>For example, let's say we want to restrict <tt class="docutils literal"><span class="pre">depth_first_search()</span></tt> so that |
---|
750 | the <tt class="docutils literal"><span class="pre">graph</span></tt> parameter is required and the <tt class="docutils literal"><span class="pre">root_vertex</span></tt> |
---|
751 | parameter is convertible to <tt class="docutils literal"><span class="pre">int</span></tt>. We might write:</p> |
---|
752 | <pre class="literal-block"> |
---|
753 | #include <boost/type_traits/is_convertible.hpp> |
---|
754 | #include <boost/mpl/placeholders.hpp> |
---|
755 | namespace graphs |
---|
756 | { |
---|
757 | using namespace boost::mpl::placeholders; |
---|
758 | |
---|
759 | struct dfs_params |
---|
760 | : parameter::parameters< |
---|
761 | <strong>parameter::required<tag::graph></strong> |
---|
762 | , parameter::optional<tag::visitor> |
---|
763 | , <strong>parameter::optional< |
---|
764 | tag::root_vertex, boost::is_convertible<_,int> |
---|
765 | ></strong> |
---|
766 | , parameter::optional<tag::index_map> |
---|
767 | , parameter::optional<tag::color_map> |
---|
768 | > |
---|
769 | {}; |
---|
770 | } |
---|
771 | </pre> |
---|
772 | </div> |
---|
773 | <div class="section" id="applying-sfinae-to-the-overload-set"> |
---|
774 | <h3><a class="toc-backref" href="#id38" name="applying-sfinae-to-the-overload-set">2.7.2 Applying SFINAE to the Overload Set</a></h3> |
---|
775 | <p>Now we add a special defaulted argument to each of our |
---|
776 | <tt class="docutils literal"><span class="pre">depth_first_search</span></tt> overloads:</p> |
---|
777 | <pre class="literal-block"> |
---|
778 | namespace graphs |
---|
779 | { |
---|
780 | template <class A0> |
---|
781 | void depth_first_search( |
---|
782 | A0 const& a0 |
---|
783 | , typename dfs_params::match<A0>::type p = dfs_params()) |
---|
784 | { |
---|
785 | core::depth_first_search(<strong>p</strong>(a0)); |
---|
786 | } |
---|
787 | |
---|
788 | template <class A0, class A1> |
---|
789 | void depth_first_search( |
---|
790 | A0 const& a0, A1 const& a1 |
---|
791 | , typename dfs_params::match<A0,A1>::type p = dfs_params()) |
---|
792 | { |
---|
793 | core::depth_first_search(<strong>p</strong>(a0,a1)); |
---|
794 | } <span class="vellipsis"> |
---|
795 | . |
---|
796 | . |
---|
797 | . |
---|
798 | </span> |
---|
799 | template <class A0, class A1, …class A4> |
---|
800 | void depth_first_search( |
---|
801 | A0 const& a0, A1 const& a1, …A4 const& A4 |
---|
802 | , typename dfs_params::match<A0,A1,A2,A3,A4>::type p = dfs_params()) |
---|
803 | { |
---|
804 | core::depth_first_search(<strong>p</strong>(a0,a1,a2,a3,a4)); |
---|
805 | } |
---|
806 | } |
---|
807 | </pre> |
---|
808 | <p>These additional parameters are not intended to be used directly |
---|
809 | by callers; they merely trigger SFINAE by becoming illegal types |
---|
810 | when the <tt class="docutils literal"><span class="pre">name</span></tt> argument is not convertible to <tt class="docutils literal"><span class="pre">const</span> |
---|
811 | <span class="pre">char*</span></tt>. The <tt class="docutils literal"><span class="pre">BOOST_PARAMETER_FUN</span></tt> macro described earlier |
---|
812 | adds these extra function parameters for you (Borland users see |
---|
813 | this <a class="reference" href="#default-arguments-unsupported-on-nested-templates">note</a>).</p> |
---|
814 | </div> |
---|
815 | <div class="section" id="reducing-boilerplate-with-macros"> |
---|
816 | <h3><a class="toc-backref" href="#id39" name="reducing-boilerplate-with-macros">2.7.3 Reducing Boilerplate With Macros</a></h3> |
---|
817 | <p>The library provides a macro you can use to eliminate some of the |
---|
818 | repetetiveness of the declaring the optional parameters. |
---|
819 | <tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MATCH</span></tt> takes three arguments: the |
---|
820 | <span class="concept">ParameterSpec</span>, a <a class="reference" href="http://boost-consulting.com/mplbook/preprocessor.html#sequences">Boost.Preprocessor sequence</a> of the function |
---|
821 | argument types, and a name for the defaulted function parameter |
---|
822 | (<tt class="docutils literal"><span class="pre">p</span></tt>, above), and it generates the appropriate defaulted |
---|
823 | argument. So we could shorten the overload set definition as |
---|
824 | follows:</p> |
---|
825 | <pre class="literal-block"> |
---|
826 | namespace graphs |
---|
827 | { |
---|
828 | template <class A0> |
---|
829 | void depth_first_search( |
---|
830 | A0 const& a0 |
---|
831 | , <strong>BOOST_PARAMETER_MATCH(dfs_params, (A0), p)</strong>) |
---|
832 | { |
---|
833 | core::depth_first_search(p(a0)); |
---|
834 | } |
---|
835 | |
---|
836 | template <class A0, class A1> |
---|
837 | void depth_first_search( |
---|
838 | A0 const& a0, A1 const& a1 |
---|
839 | , <strong>BOOST_PARAMETER_MATCH(dfs_params, (A0)(A1), p)</strong>) |
---|
840 | { |
---|
841 | core::depth_first_search(p(a0,a1)); |
---|
842 | } <span class="vellipsis"> |
---|
843 | . |
---|
844 | . |
---|
845 | . |
---|
846 | </span> |
---|
847 | template <class A0, class A1, …class A4> |
---|
848 | void depth_first_search( |
---|
849 | A0 const& a0, A1 const& a1, …A4 const& A4 |
---|
850 | , <strong>BOOST_PARAMETER_MATCH(dfs_params, (A0)(A1)…(A4), p)</strong>) |
---|
851 | { |
---|
852 | core::depth_first_search(p(a0,a1,a2,a3,a4)); |
---|
853 | } |
---|
854 | } |
---|
855 | </pre> |
---|
856 | </div> |
---|
857 | </div> |
---|
858 | <div class="section" id="efficiency-issues"> |
---|
859 | <h2><a class="toc-backref" href="#id40" name="efficiency-issues">2.8 Efficiency Issues</a></h2> |
---|
860 | <p>The <tt class="docutils literal"><span class="pre">color_map</span></tt> parameter gives us a few efficiency issues to |
---|
861 | consider. Here's a first cut at extraction and binding:</p> |
---|
862 | <pre class="literal-block"> |
---|
863 | typedef |
---|
864 | vector_property_map<boost::default_color_type, Index> |
---|
865 | default_color_map; |
---|
866 | |
---|
867 | typename parameter::binding< |
---|
868 | ArgumentPack |
---|
869 | , tag::color_map |
---|
870 | , default_color_map |
---|
871 | >::type color = args[color_map|<strong>default_color_map(num_vertices(g),i)</strong>]; |
---|
872 | </pre> |
---|
873 | <div class="section" id="eliminating-copies"> |
---|
874 | <h3><a class="toc-backref" href="#id41" name="eliminating-copies">2.8.1 Eliminating Copies</a></h3> |
---|
875 | <p>The library has no way to know whether an explicitly-supplied |
---|
876 | argument is expensive to copy (or even if it is copyable at all), |
---|
877 | so <tt class="docutils literal"><span class="pre">binding<…,k,…>::type</span></tt> is always a reference type when the |
---|
878 | <em>k</em> parameter is supplied by the caller. Since <tt class="docutils literal"><span class="pre">args[…]</span></tt> |
---|
879 | yields a reference to the actual argument, <tt class="docutils literal"><span class="pre">color</span></tt> will be bound |
---|
880 | to the actual <tt class="docutils literal"><span class="pre">color_map</span></tt> argument and no copying will be done.</p> |
---|
881 | <p>As described <a class="reference" href="#dangling">above</a>, because the default is a temporary, it's |
---|
882 | important that <tt class="docutils literal"><span class="pre">color</span></tt> be a non-reference when the default is |
---|
883 | used. In that case, the default value will be <em>copied</em> into |
---|
884 | <tt class="docutils literal"><span class="pre">color</span></tt>. If we store the default in a named variable, though, |
---|
885 | <tt class="docutils literal"><span class="pre">color</span></tt> can be a reference, thereby eliminating the copy:</p> |
---|
886 | <pre class="literal-block"> |
---|
887 | default_color_map default_color(num_vertices(g),i); |
---|
888 | |
---|
889 | typename parameter::binding< |
---|
890 | ArgumentPack |
---|
891 | , tag::color_map |
---|
892 | , <strong>default_color_map&</strong> |
---|
893 | >::type color = args[color_map|default_color]; |
---|
894 | </pre> |
---|
895 | <div class="hint"> |
---|
896 | <p class="first admonition-title">Hint</p> |
---|
897 | <p class="last">To avoid making needless copies, pass a <em>reference to the |
---|
898 | default type</em> as the third argument to <tt class="docutils literal"><span class="pre">binding</span></tt>.</p> |
---|
899 | </div> |
---|
900 | </div> |
---|
901 | <div class="section" id="lazy-default-computation"> |
---|
902 | <h3><a class="toc-backref" href="#id42" name="lazy-default-computation">2.8.2 Lazy Default Computation</a></h3> |
---|
903 | <p>Of course it's nice to avoid copying <tt class="docutils literal"><span class="pre">default_color</span></tt>, but the |
---|
904 | more important cost is that of <em>constructing</em> it in the first |
---|
905 | place. A <tt class="docutils literal"><span class="pre">vector_property_map</span></tt> is cheap to copy, since it holds |
---|
906 | its elements via a <a class="reference" href="../../../smart_ptr/shared_ptr.htm"><tt class="docutils literal"><span class="pre">shared_ptr</span></tt></a>. On the other hand, construction of |
---|
907 | <tt class="docutils literal"><span class="pre">default_color</span></tt> costs at least two dynamic memory allocations and |
---|
908 | <tt class="docutils literal"><span class="pre">num_vertices(g)</span></tt> copies; it would be better to avoid doing this |
---|
909 | work when the default value won't be needed.</p> |
---|
910 | <p>To that end, the library allows us to supply a callable object |
---|
911 | that—if no argument was supplied by the caller—will be invoked to |
---|
912 | construct the default value. Instead of following the keyword with |
---|
913 | the <tt class="docutils literal"><span class="pre">|</span></tt> operator, we'll use <tt class="docutils literal"><span class="pre">||</span></tt> and follow it with a |
---|
914 | nullary (zero-argument) function object that constructs a |
---|
915 | default_color_map. Here, we build the function object using |
---|
916 | <a class="reference" href="../../../lambda/index.html">Boost.Lambda</a>:<a class="footnote-reference" href="#bind" id="id15" name="id15"><sup>4</sup></a></p> |
---|
917 | <pre class="literal-block"> |
---|
918 | // After #include <boost/lambda/construct.hpp> |
---|
919 | typename parameter::binding< |
---|
920 | ArgumentPack |
---|
921 | , tag::color_map |
---|
922 | , default_color_map |
---|
923 | >::type color = args[ |
---|
924 | color_map |
---|
925 | <strong>|| boost::lambda::construct<default_color_map>(num_vertices(g),i)</strong> |
---|
926 | ]; |
---|
927 | </pre> |
---|
928 | <div class="sidebar"> |
---|
929 | <p class="first sidebar-title">Mnemonics</p> |
---|
930 | <p class="last">To remember the difference between <tt class="docutils literal"><span class="pre">|</span></tt> and <tt class="docutils literal"><span class="pre">||</span></tt>, recall that |
---|
931 | <tt class="docutils literal"><span class="pre">||</span></tt> normally uses short-circuit evaluation: its second |
---|
932 | argument is only evaluated if its first argument is <tt class="docutils literal"><span class="pre">false</span></tt>. |
---|
933 | Similarly, in <tt class="docutils literal"><span class="pre">color_map[param||f]</span></tt>, <tt class="docutils literal"><span class="pre">f</span></tt> is only invoked if |
---|
934 | no <tt class="docutils literal"><span class="pre">color_map</span></tt> argument was supplied.</p> |
---|
935 | </div> |
---|
936 | </div> |
---|
937 | <div class="section" id="default-forwarding"> |
---|
938 | <h3><a class="toc-backref" href="#id43" name="default-forwarding">2.8.3 Default Forwarding</a></h3> |
---|
939 | <p>Types that are expensive to construct yet cheap to copy aren't all |
---|
940 | that typical, and even copying the color map is more expensive than |
---|
941 | we might like. It might be nice to avoid both needless |
---|
942 | construction <em>and</em> needless copying of the default color map. The |
---|
943 | simplest way to achieve that is to avoid naming it altogether, at |
---|
944 | least not in <tt class="docutils literal"><span class="pre">core::depth_first_search</span></tt>. Instead, we'll |
---|
945 | introduce another function template to implement the actual |
---|
946 | algorithm:</p> |
---|
947 | <pre class="literal-block"> |
---|
948 | namespace graphs { namespace core |
---|
949 | { |
---|
950 | template <class G, class V, class S, class I, class C> |
---|
951 | void <strong>dfs_impl</strong>(G& g, V& v, S& s, I& i, C& c) |
---|
952 | { |
---|
953 | <em>…actual algorithm implementation…</em> |
---|
954 | } |
---|
955 | }} |
---|
956 | </pre> |
---|
957 | <p>Then, in <tt class="docutils literal"><span class="pre">core::depth_first_search</span></tt>, we'll simply forward the |
---|
958 | result of indexing <tt class="docutils literal"><span class="pre">args</span></tt> to <tt class="docutils literal"><span class="pre">core::dfs_impl</span></tt>:</p> |
---|
959 | <pre class="literal-block"> |
---|
960 | core::dfs_impl( |
---|
961 | g,v,s,i |
---|
962 | , args[ |
---|
963 | color_map |
---|
964 | || boost::lambda::construct<default_color_map>(num_vertices(g),i) |
---|
965 | ]); |
---|
966 | </pre> |
---|
967 | <p>In real code, after going to the trouble to write <tt class="docutils literal"><span class="pre">dfs_impl</span></tt>, |
---|
968 | we'd probably just forward all the arguments.</p> |
---|
969 | </div> |
---|
970 | <div class="section" id="dispatching-based-on-the-presence-of-a-default"> |
---|
971 | <h3><a class="toc-backref" href="#id44" name="dispatching-based-on-the-presence-of-a-default">2.8.4 Dispatching Based on the Presence of a Default</a></h3> |
---|
972 | <p>In fact, the Graph library itself constructs a slightly different |
---|
973 | <tt class="docutils literal"><span class="pre">color_map</span></tt>, to avoid even the overhead of initializing a |
---|
974 | <a class="reference" href="../../../smart_ptr/shared_ptr.htm"><tt class="docutils literal"><span class="pre">shared_ptr</span></tt></a>:</p> |
---|
975 | <pre class="literal-block"> |
---|
976 | std::vector<boost::default_color_type> |
---|
977 | color_vec(num_vertices(g)); |
---|
978 | |
---|
979 | boost::iterator_property_map< |
---|
980 | typename std::vector< |
---|
981 | boost::default_color_type |
---|
982 | >::iterator |
---|
983 | , Index |
---|
984 | > c(color_vec.begin(), i); |
---|
985 | </pre> |
---|
986 | <p>To avoid instantiating that code when it isn't needed, we'll have |
---|
987 | to find a way to select different function implementations, at |
---|
988 | compile time, based on whether a <tt class="docutils literal"><span class="pre">color_map</span></tt> argument was |
---|
989 | supplied. By using <a class="reference" href="../../../../more/generic_programming.html#tag_dispatching">tag dispatching</a> on the presence of a |
---|
990 | <tt class="docutils literal"><span class="pre">color_map</span></tt> argument, we can do just that:</p> |
---|
991 | <pre class="literal-block"> |
---|
992 | #include <boost/type_traits/is_same.hpp> |
---|
993 | #include <boost/mpl/bool.hpp> |
---|
994 | |
---|
995 | namespace graphs { namespace core { |
---|
996 | |
---|
997 | template <class ArgumentPack> |
---|
998 | void dfs_dispatch(ArgumentPack& args, <strong>mpl::true_</strong>) |
---|
999 | { |
---|
1000 | <em>…use the color map computed in the previous example…</em> |
---|
1001 | } |
---|
1002 | |
---|
1003 | template <class ArgumentPack> |
---|
1004 | void dfs_dispatch(ArgumentPack& args, <strong>mpl::false_</strong>) |
---|
1005 | { |
---|
1006 | <em>…use args[color]…</em> |
---|
1007 | } |
---|
1008 | |
---|
1009 | template <class ArgumentPack> |
---|
1010 | void depth_first_search(ArgumentPack& args) |
---|
1011 | { |
---|
1012 | typedef typename binding<args,tag::color>::type color_; |
---|
1013 | core::dfs_dispatch(args, <strong>boost::is_same<color_,void>()</strong>); |
---|
1014 | } |
---|
1015 | }} |
---|
1016 | </pre> |
---|
1017 | <p>We've used the fact that the default for <tt class="docutils literal"><span class="pre">binding</span></tt>'s third |
---|
1018 | argument is <tt class="docutils literal"><span class="pre">void</span></tt>: because specializations of <tt class="docutils literal"><span class="pre">is_same</span></tt> are |
---|
1019 | <tt class="docutils literal"><span class="pre">bool</span></tt>-valued MPL <a class="reference" href="../../../mpl/doc/refmanual/integral-constant.html"><span class="concept">Integral Constant</span></a>s derived either |
---|
1020 | from <tt class="docutils literal"><span class="pre">mpl::true_</span></tt> or <tt class="docutils literal"><span class="pre">mpl::false_</span></tt>, the appropriate |
---|
1021 | <tt class="docutils literal"><span class="pre">dfs_dispatch</span></tt> implementation will be selected.</p> |
---|
1022 | </div> |
---|
1023 | </div> |
---|
1024 | </div> |
---|
1025 | <div class="section" id="portability-considerations"> |
---|
1026 | <h1><a class="toc-backref" href="#id45" name="portability-considerations">3 Portability Considerations</a></h1> |
---|
1027 | <p>Use the <a class="reference" href="http://www.boost.org/regression/release/user/parameter.html">regression test results</a> for the latest Boost release of |
---|
1028 | the Parameter library to see how it fares on your favorite |
---|
1029 | compiler. Additionally, you may need to be aware of the following |
---|
1030 | issues and workarounds for particular compilers.</p> |
---|
1031 | <div class="section" id="no-sfinae-support"> |
---|
1032 | <h2><a class="toc-backref" href="#id46" name="no-sfinae-support">3.1 No SFINAE Support</a></h2> |
---|
1033 | <p>Some older compilers don't support SFINAE. If your compiler meets |
---|
1034 | that criterion, then Boost headers will <tt class="docutils literal"><span class="pre">#define</span></tt> the preprocessor |
---|
1035 | symbol <tt class="docutils literal"><span class="pre">BOOST_NO_SFINAE</span></tt>, and uses of <tt class="docutils literal"><span class="pre">parameters<…>::match</span></tt> and |
---|
1036 | <tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MATCH</span></tt> will be harmless, but will have no effect.</p> |
---|
1037 | </div> |
---|
1038 | <div class="section" id="no-support-for-result-of"> |
---|
1039 | <h2><a name="no-support-for-result-of">3.2 No Support for <a class="reference" href="../../../utility/utility.htm#result_of"><tt class="docutils literal"><span class="pre">result_of</span></tt></a></a></h2> |
---|
1040 | <p><a class="reference" href="#lazy-default-computation">Lazy default computation</a> relies on the <tt class="docutils literal"><span class="pre">result_of</span></tt> class |
---|
1041 | template to compute the types of default arguments given the type |
---|
1042 | of the function object that constructs them. On compilers that |
---|
1043 | don't support <tt class="docutils literal"><span class="pre">result_of</span></tt>, <tt class="docutils literal"><span class="pre">BOOST_NO_RESULT_OF</span></tt> will be |
---|
1044 | <tt class="docutils literal"><span class="pre">#define</span></tt>d, and the compiler will expect the function object to |
---|
1045 | contain a nested type name, <tt class="docutils literal"><span class="pre">result_type</span></tt>, that indicates its |
---|
1046 | return type when invoked without arguments. To use an ordinary |
---|
1047 | function as a default generator on those compilers, you'll need to |
---|
1048 | wrap it in a class that provides <tt class="docutils literal"><span class="pre">result_type</span></tt> as a <tt class="docutils literal"><span class="pre">typedef</span></tt> |
---|
1049 | and invokes the function via its <tt class="docutils literal"><span class="pre">operator()</span></tt>.</p> |
---|
1050 | </div> |
---|
1051 | <div class="section" id="can-t-declare-parameterspec-via-typedef"> |
---|
1052 | <h2><a class="toc-backref" href="#id48" name="can-t-declare-parameterspec-via-typedef">3.3 Can't Declare <span class="concept">ParameterSpec</span> via <tt class="docutils literal"><span class="pre">typedef</span></tt></a></h2> |
---|
1053 | <p>In principle you can declare a <span class="concept">ParameterSpec</span> as a <tt class="docutils literal"><span class="pre">typedef</span></tt> |
---|
1054 | for a specialization of <tt class="docutils literal"><span class="pre">parameters<…></span></tt>, but Microsoft Visual C++ |
---|
1055 | 6.x has been seen to choke on that usage. The workaround is to use |
---|
1056 | inheritance and declare your <span class="concept">ParameterSpec</span> as a class:</p> |
---|
1057 | <pre class="literal-block"> |
---|
1058 | <strong>struct dfs_parameters |
---|
1059 | :</strong> parameter::parameters< |
---|
1060 | tag::graph, tag::visitor, tag::root_vertex |
---|
1061 | , tag::index_map, tag::color_map |
---|
1062 | > <strong>{};</strong> |
---|
1063 | </pre> |
---|
1064 | </div> |
---|
1065 | <div class="section" id="default-arguments-unsupported-on-nested-templates"> |
---|
1066 | <h2><a class="toc-backref" href="#id49" name="default-arguments-unsupported-on-nested-templates">3.4 Default Arguments Unsupported on Nested Templates</a></h2> |
---|
1067 | <p>As of this writing, Borland compilers don't support the use of |
---|
1068 | default template arguments on member class templates. As a result, |
---|
1069 | you have to supply <tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MAX_ARITY</span></tt> arguments to every |
---|
1070 | use of <tt class="docutils literal"><span class="pre">parameters<…>::match</span></tt>. Since the actual defaults used |
---|
1071 | are unspecified, the workaround is to use |
---|
1072 | <a class="reference" href="#default-arguments-unsupported-on-nested-templates"><tt class="docutils literal"><span class="pre">BOOST_PARAMETER_MATCH</span></tt></a> to declare default arguments for SFINAE.</p> |
---|
1073 | </div> |
---|
1074 | <div class="section" id="compiler-can-t-see-references-in-unnamed-namespace"> |
---|
1075 | <h2><a class="toc-backref" href="#id50" name="compiler-can-t-see-references-in-unnamed-namespace">3.5 Compiler Can't See References In Unnamed Namespace</a></h2> |
---|
1076 | <p>If you use Microsoft Visual C++ 6.x, you may find that the compiler |
---|
1077 | has trouble finding your keyword objects. This problem has been |
---|
1078 | observed, but only on this one compiler, and it disappeared as the |
---|
1079 | test code evolved, so we suggest you use it only as a last resort |
---|
1080 | rather than as a preventative measure. The solution is to add |
---|
1081 | <em>using-declarations</em> to force the names to be available in the |
---|
1082 | enclosing namespace without qualification:</p> |
---|
1083 | <pre class="literal-block"> |
---|
1084 | namespace graphs |
---|
1085 | { |
---|
1086 | using graphs::graph; |
---|
1087 | using graphs::visitor; |
---|
1088 | using graphs::root_vertex; |
---|
1089 | using graphs::index_map; |
---|
1090 | using graphs::color_map; |
---|
1091 | } |
---|
1092 | </pre> |
---|
1093 | </div> |
---|
1094 | </div> |
---|
1095 | <div class="section" id="reference"> |
---|
1096 | <h1><a class="toc-backref" href="#id51" name="reference">4 Reference</a></h1> |
---|
1097 | <p>Follow <a class="reference" href="reference.html">this link</a> to the Boost.Parameter reference |
---|
1098 | documentation.</p> |
---|
1099 | </div> |
---|
1100 | <div class="section" id="acknowledgements"> |
---|
1101 | <h1><a class="toc-backref" href="#id52" name="acknowledgements">5 Acknowledgements</a></h1> |
---|
1102 | <p>The authors would like to thank all the Boosters who participated |
---|
1103 | in the review of this library and its documentation, most |
---|
1104 | especially our review manager, Doug Gregor.</p> |
---|
1105 | <hr class="docutils" /> |
---|
1106 | <table class="docutils footnote" frame="void" id="old-interface" rules="none"> |
---|
1107 | <colgroup><col class="label" /><col /></colgroup> |
---|
1108 | <tbody valign="top"> |
---|
1109 | <tr><td class="label"><a class="fn-backref" href="#id2" name="old-interface">[1]</a></td><td>As of Boost 1.33.0 the Graph library was still |
---|
1110 | using an <a class="reference" href="../../../graph/doc/bgl_named_params.html">older named parameter mechanism</a>, but there are |
---|
1111 | plans to change it to use Boost.Parameter (this library) in an |
---|
1112 | upcoming release, while keeping the old interface available for |
---|
1113 | backward-compatibility.</td></tr> |
---|
1114 | </tbody> |
---|
1115 | </table> |
---|
1116 | <table class="docutils footnote" frame="void" id="odr" rules="none"> |
---|
1117 | <colgroup><col class="label" /><col /></colgroup> |
---|
1118 | <tbody valign="top"> |
---|
1119 | <tr><td class="label"><a class="fn-backref" href="#id5" name="odr">[2]</a></td><td>The <strong>One Definition Rule</strong> says that any given entity in |
---|
1120 | a C++ program must have the same definition in all translation |
---|
1121 | units (object files) that make up a program.</td></tr> |
---|
1122 | </tbody> |
---|
1123 | </table> |
---|
1124 | <table class="docutils footnote" frame="void" id="vertex-descriptor" rules="none"> |
---|
1125 | <colgroup><col class="label" /><col /></colgroup> |
---|
1126 | <tbody valign="top"> |
---|
1127 | <tr><td class="label"><a class="fn-backref" href="#id6" name="vertex-descriptor">[3]</a></td><td>If you're not familiar with the Boost Graph |
---|
1128 | Library, don't worry about the meaning of any |
---|
1129 | Graph-library-specific details you encounter. In this case you |
---|
1130 | could replace all mentions of vertex descriptor types with |
---|
1131 | <tt class="docutils literal"><span class="pre">int</span></tt> in the text, and your understanding of the Parameter |
---|
1132 | library wouldn't suffer.</td></tr> |
---|
1133 | </tbody> |
---|
1134 | </table> |
---|
1135 | <table class="docutils footnote" frame="void" id="bind" rules="none"> |
---|
1136 | <colgroup><col class="label" /><col /></colgroup> |
---|
1137 | <tbody valign="top"> |
---|
1138 | <tr><td class="label"><a class="fn-backref" href="#id15" name="bind">[4]</a></td><td><p class="first">The Lambda library is known not to work on <a class="reference" href="http://www.boost.org/regression/release/user/lambda.html">some |
---|
1139 | less-conformant compilers</a>. When using one of those you could |
---|
1140 | define</p> |
---|
1141 | <pre class="last literal-block"> |
---|
1142 | template <class T> |
---|
1143 | struct construct2 |
---|
1144 | { |
---|
1145 | typedef T result_type; |
---|
1146 | |
---|
1147 | template <class A1, class A2> |
---|
1148 | T operator()(A1 a1, A2 a2) { return T(a1,a2); } |
---|
1149 | }; |
---|
1150 | |
---|
1151 | and use `Boost.Bind`_ to generate the function object:: |
---|
1152 | |
---|
1153 | boost::bind(construct2<default_color_map>(),num_vertices(g),i) |
---|
1154 | </pre> |
---|
1155 | </td></tr> |
---|
1156 | </tbody> |
---|
1157 | </table> |
---|
1158 | <table class="docutils footnote" frame="void" id="using" rules="none"> |
---|
1159 | <colgroup><col class="label" /><col /></colgroup> |
---|
1160 | <tbody valign="top"> |
---|
1161 | <tr><td class="label"><a class="fn-backref" href="#id9" name="using">[5]</a></td><td><p class="first">You can always give the illusion that the function |
---|
1162 | lives in an outer namespace by applying a <em>using-declaration</em>:</p> |
---|
1163 | <pre class="last literal-block"> |
---|
1164 | namespace foo_overloads |
---|
1165 | { |
---|
1166 | // foo declarations here |
---|
1167 | void foo() { ... } |
---|
1168 | ... |
---|
1169 | } |
---|
1170 | using foo_overloads::foo; |
---|
1171 | </pre> |
---|
1172 | </td></tr> |
---|
1173 | </tbody> |
---|
1174 | </table> |
---|
1175 | <table class="docutils footnote" frame="void" id="sfinae" rules="none"> |
---|
1176 | <colgroup><col class="label" /><col /></colgroup> |
---|
1177 | <tbody valign="top"> |
---|
1178 | <tr><td class="label"><a class="fn-backref" href="#id11" name="sfinae">[6]</a></td><td>If type substitution during the instantiation of a |
---|
1179 | function template results in an invalid type, no compilation |
---|
1180 | error is emitted; instead the overload is removed from the |
---|
1181 | overload set. By producing an invalid type in the function |
---|
1182 | signature depending on the result of some condition, whether or |
---|
1183 | not an overload is considered during overload resolution can be |
---|
1184 | controlled. The technique is formalized in the <a class="reference" href="../../../utility/enable_if.html"><tt class="docutils literal"><span class="pre">enable_if</span></tt></a> |
---|
1185 | utility. See |
---|
1186 | <a class="reference" href="http://www.semantics.org/once_weakly/w02_SFINAE.pdf">http://www.semantics.org/once_weakly/w02_SFINAE.pdf</a> for more |
---|
1187 | information on SFINAE.</td></tr> |
---|
1188 | </tbody> |
---|
1189 | </table> |
---|
1190 | </div> |
---|
1191 | </div> |
---|
1192 | <hr class="docutils footer" /> |
---|
1193 | <div class="footer"> |
---|
1194 | Generated on: 2005-08-13 01:16 UTC. |
---|
1195 | Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source. |
---|
1196 | </div> |
---|
1197 | </body> |
---|
1198 | </html> |
---|