1 +++++++++++++++++++++++++++++++++++++++++++++++++
2 The Boost Parameter Library
3 +++++++++++++++++++++++++++++++++++++++++++++++++
7 .. |(logo)| image:: ../../../../boost.png
10 __ ../../../../index.htm
12 -------------------------------------
14 :Abstract: Use this library to write functions and class templates
15 that can accept arguments by name:
19 new_window("alert", **_width=10**, **_titlebar=false**);
23 , **deleter<Deallocate<Foo> >**
24 , **copy_policy<DeepCopy>** > p(new Foo);
26 Since named arguments can be passed in any order, they are
27 especially useful when a function or template has more than one
28 parameter with a useful default value. The library also supports
29 *deduced* parameters; that is to say, parameters whose identity
30 can be deduced from their types.
32 .. @jam_prefix.append('''
33 project test : requirements <include>. <implicit-dependency>/boost//headers ;''')
35 .. @example.prepend('''
36 #include <boost/parameter.hpp>
40 BOOST_PARAMETER_NAME(title)
41 BOOST_PARAMETER_NAME(width)
42 BOOST_PARAMETER_NAME(titlebar)
44 BOOST_PARAMETER_FUNCTION(
45 (int), new_window, tag, (required (title,*)(width,*)(titlebar,*)))
50 BOOST_PARAMETER_TEMPLATE_KEYWORD(deleter)
51 BOOST_PARAMETER_TEMPLATE_KEYWORD(copy_policy)
53 template <class T> struct Deallocate {};
56 namespace parameter = boost::parameter;
59 template <class T, class A0, class A1>
71 -------------------------------------
73 :Authors: David Abrahams, Daniel Wallin
74 :Contact: dave@boost-consulting.com, daniel@boostpro.com
75 :organization: `BoostPro Computing`_
76 :date: $Date: 2005/07/17 19:53:01 $
78 :copyright: Copyright David Abrahams, Daniel Wallin
79 2005-2009. Distributed under the Boost Software License,
80 Version 1.0. (See accompanying file LICENSE_1_0.txt
81 or copy at http://www.boost.org/LICENSE_1_0.txt)
83 .. _`BoostPro Computing`: http://www.boostpro.com
85 .. _concepts: http://www.boost.org/more/generic_programming.html#concept
87 -------------------------------------
89 [Note: this tutorial does not cover all details of the library. Please see also the `reference documentation`__\ ]
93 .. contents:: **Table of Contents**
102 .. section-numbering::
104 -------------------------------------
110 In C++, arguments_ are normally given meaning by their positions
111 with respect to a parameter_ list: the first argument passed maps
112 onto the first parameter in a function's definition, and so on.
113 That protocol is fine when there is at most one parameter with a
114 default value, but when there are even a few useful defaults, the
115 positional interface becomes burdensome:
119 Since an argument's meaning is given by its position, we have to
120 choose an (often arbitrary) order for parameters with default
121 values, making some combinations of defaults unusable:
127 **int border_width = default_border_width,**
129 bool initially_visible = true
132 const bool movability = false;
133 window* w = new_window("alert box", movability);
135 In the example above we wanted to make an unmoveable window
136 with a default ``border_width``, but instead we got a moveable
137 window with a ``border_width`` of zero. To get the desired
138 effect, we'd need to write:
142 window* w = new_window(
143 "alert box", **default_border_width**, movability);
147 It can become difficult for readers to understand the meaning of
148 arguments at the call site::
150 window* w = new_window("alert", 1, true, false);
152 Is this window moveable and initially invisible, or unmoveable
153 and initially visible? The reader needs to remember the order
154 of arguments to be sure.
156 * The author of the call may not remember the order of the
157 arguments either, leading to hard-to-find bugs.
161 -------------------------
162 Named Function Parameters
163 -------------------------
167 This library addresses the problems outlined above by associating
168 each parameter name with a keyword object. Now users can identify
169 arguments by name, rather than by position:
173 window* w = new_window("alert box", **movable_=**\ false); // OK!
177 ---------------------------
178 Deduced Function Parameters
179 ---------------------------
183 A **deduced parameter** can be passed in any position *without*
184 supplying an explicit parameter name. It's not uncommon for a
185 function to have parameters that can be uniquely identified based
186 on the types of arguments passed. The ``name`` parameter to
187 ``new_window`` is one such example. None of the other arguments,
188 if valid, can reasonably be converted to a ``char const*``. With
189 a deduced parameter interface, we could pass the window name in
190 *any* argument position without causing ambiguity:
194 window* w = new_window(movable_=false, **"alert box"**); // OK!
195 window* w = new_window(**"alert box"**, movable_=false); // OK!
197 Appropriately used, a deduced parameter interface can free the
198 user of the burden of even remembering the formal parameter
203 --------------------------------
204 Class Template Parameter Support
205 --------------------------------
209 The reasoning we've given for named and deduced parameter
210 interfaces applies equally well to class templates as it does to
211 functions. Using the Parameter library, we can create interfaces
212 that allow template arguments (in this case ``shared`` and
213 ``Client``) to be explicitly named, like this:
217 smart_ptr<**ownership<shared>**, **value_type<Client>** > p;
219 The syntax for passing named template arguments is not quite as
220 natural as it is for function arguments (ideally, we'd be able to
221 write ``smart_ptr<ownership=shared,…>``). This small syntactic
222 deficiency makes deduced parameters an especially big win when
223 used with class templates:
227 // *p and q could be equivalent, given a deduced*
228 // *parameter interface.*
229 smart_ptr<**shared**, **Client**> p;
230 smart_ptr<**Client**, **shared**> q;
238 This tutorial shows all the basics—how to build both named- and deduced-parameter
239 interfaces to function templates and class templates—and several
240 more advanced idioms as well.
242 ---------------------------
243 Parameter-Enabled Functions
244 ---------------------------
246 In this section we'll show how the Parameter library can be used to
247 build an expressive interface to the `Boost Graph library`__\ 's
248 |dfs|_ algorithm. [#old_interface]_
252 After laying some groundwork
253 and describing the algorithm's abstract interface, we'll show you
254 how to build a basic implementation with keyword support. Then
255 we'll add support for default arguments and we'll gradually refine the
256 implementation with syntax improvements. Finally we'll show how to
257 streamline the implementation of named parameter interfaces,
258 improve their participation in overload resolution, and optimize
259 their runtime efficiency.
261 __ ../../../graph/index.html
263 .. _dfs: ../../../graph/doc/depth_first_search.html
265 .. |dfs| replace:: ``depth_first_search``
268 Headers And Namespaces
269 ======================
271 Most components of the Parameter library are declared in a
272 header named for the component. For example, ::
274 #include <boost/parameter/keyword.hpp>
276 will ensure ``boost::parameter::keyword`` is known to the
277 compiler. There is also a combined header,
278 ``boost/parameter.hpp``, that includes most of the library's
279 components. For the the rest of this tutorial, unless we say
280 otherwise, you can use the rule above to figure out which header
281 to ``#include`` to access any given component of the library.
283 .. @example.append('''
284 using boost::parameter::keyword;
289 Also, the examples below will also be written as if the
292 namespace parameter = boost::parameter;
296 has been declared: we'll write ``parameter::xxx`` instead of
297 ``boost::parameter::xxx``.
299 The Abstract Interface to |dfs|
300 ===============================
302 The Graph library's |dfs| algorithm is a generic function accepting
303 from one to four arguments by reference. If all arguments were
304 required, its signature might be as follows::
307 class Graph, class DFSVisitor, class Index, class ColorMap
309 void depth_first_search(
312 , typename graph_traits<g>::vertex_descriptor root_vertex
318 However, most of the parameters have a useful default value, as
319 shown in the table below.
321 .. _`parameter table`:
322 .. _`default expressions`:
324 .. table:: ``depth_first_search`` Parameters
326 +----------------+----------+---------------------------------+----------------------------------+
327 | Parameter Name | Dataflow | Type | Default Value (if any) |
328 +================+==========+=================================+==================================+
329 |``graph`` | in |Model of |IncidenceGraph|_ and |none - this argument is required. |
330 | | ||VertexListGraph|_ | |
332 +----------------+----------+---------------------------------+----------------------------------+
333 |``visitor`` | in |Model of |DFSVisitor|_ |``boost::dfs_visitor<>()`` |
334 +----------------+----------+---------------------------------+----------------------------------+
335 |``root_vertex`` | in |``graph``'s vertex descriptor |``*vertices(graph).first`` |
337 +----------------+----------+---------------------------------+----------------------------------+
338 |``index_map`` | in |Model of |ReadablePropertyMap|_ |``get(boost::vertex_index,graph)``|
339 | | |with key type := ``graph``'s | |
340 | | |vertex descriptor and value type | |
341 | | |an integer type. | |
342 +----------------+----------+---------------------------------+----------------------------------+
343 |``color_map`` | in/out |Model of |ReadWritePropertyMap|_ |an ``iterator_property_map`` |
344 | | |with key type := ``graph``'s |created from a ``std::vector`` of |
345 | | |vertex descriptor type. |``default_color_type`` of size |
346 | | | |``num_vertices(graph)`` and using |
347 | | | |``index_map`` for the index map. |
348 +----------------+----------+---------------------------------+----------------------------------+
350 .. |IncidenceGraph| replace:: :concept:`Incidence Graph`
351 .. |VertexListGraph| replace:: :concept:`Vertex List Graph`
352 .. |DFSVisitor| replace:: :concept:`DFS Visitor`
353 .. |ReadablePropertyMap| replace:: :concept:`Readable Property Map`
354 .. |ReadWritePropertyMap| replace:: :concept:`Read/Write Property Map`
356 .. _`IncidenceGraph`: ../../../graph/doc/IncidenceGraph.html
357 .. _`VertexListGraph`: ../../../graph/doc/VertexListGraph.html
358 .. _`DFSVisitor`: ../../../graph/doc/DFSVisitor.html
359 .. _`ReadWritePropertyMap`: ../../../property_map/doc/ReadWritePropertyMap.html
360 .. _`ReadablePropertyMap`: ../../../property_map/doc/ReadablePropertyMap.html
362 Don't be intimidated by the information in the second and third
363 columns above. For the purposes of this exercise, you don't need
364 to understand them in detail.
366 Defining the Keywords
367 =====================
369 The point of this exercise is to make it possible to call
370 ``depth_first_search`` with named arguments, leaving out any
371 arguments for which the default is appropriate:
375 graphs::depth_first_search(g, **color_map_=my_color_map**);
379 To make that syntax legal, there needs to be an object called
380 “\ ``color_map_``\ ” whose assignment operator can accept a
381 ``my_color_map`` argument. In this step we'll create one such
382 **keyword object** for each parameter. Each keyword object will be
383 identified by a unique **keyword tag type**.
387 We're going to define our interface in namespace ``graphs``. Since
388 users need access to the keyword objects, but not the tag types,
389 we'll define the keyword objects so they're accessible through
390 ``graphs``, and we'll hide the tag types away in a nested
391 namespace, ``graphs::tag``. The library provides a convenient
392 macro for that purpose.
394 We're going to define our interface in namespace ``graphs``. The
395 library provides a convenient macro for defining keyword objects::
397 #include <boost/parameter/name.hpp>
401 BOOST_PARAMETER_NAME(graph) // Note: no semicolon
402 BOOST_PARAMETER_NAME(visitor)
403 BOOST_PARAMETER_NAME(root_vertex)
404 BOOST_PARAMETER_NAME(index_map)
405 BOOST_PARAMETER_NAME(color_map)
410 The declaration of the ``graph`` keyword you see here is
415 namespace tag { struct graph; } // keyword tag type
419 // A reference to the keyword object
420 boost::parameter::keyword<tag::graph>& _graph
421 = boost::parameter::keyword<tag::graph>::get();
425 .. @example.prepend('#include <boost/parameter/keyword.hpp>')
428 It defines a *keyword tag type* named ``tag::graph`` and a *keyword
429 object* reference named ``_graph``.
431 This “fancy dance” involving an unnamed namespace and references
432 is all done to avoid violating the One Definition Rule (ODR)
433 [#odr]_ when the named parameter interface is used by function
434 templates that are instantiated in multiple translation
435 units (MSVC6.x users see `this note`__).
437 __ `Compiler Can't See References In Unnamed Namespace`_
442 Now that we have our keywords defined, the function template
443 definition follows a simple pattern using the
444 ``BOOST_PARAMETER_FUNCTION`` macro::
446 #include <boost/parameter/preprocessor.hpp>
450 BOOST_PARAMETER_FUNCTION(
451 (void), // 1. parenthesized return type
452 depth_first_search, // 2. name of the function template
454 tag, // 3. namespace of tag types
456 (required (graph, *) ) // 4. one required parameter, and
458 (optional // four optional parameters, with defaults
459 (visitor, *, boost::dfs_visitor<>())
460 (root_vertex, *, *vertices(graph).first)
461 (index_map, *, get(boost::vertex_index,graph))
462 (in_out(color_map), *,
463 default_color_map(num_vertices(graph), index_map) )
467 // ... body of function goes here...
468 // use graph, visitor, index_map, and color_map
472 .. @example.prepend('''
473 #include <boost/parameter/name.hpp>
475 BOOST_PARAMETER_NAME(graph)
476 BOOST_PARAMETER_NAME(visitor)
477 BOOST_PARAMETER_NAME(root_vertex)
478 BOOST_PARAMETER_NAME(index_map)
479 BOOST_PARAMETER_NAME(color_map)
483 template <class T = int>
487 int vertex_index = 0;
493 The arguments to ``BOOST_PARAMETER_FUNCTION`` are:
495 1. The return type of the resulting function template. Parentheses
496 around the return type prevent any commas it might contain from
497 confusing the preprocessor, and are always required.
499 2. The name of the resulting function template.
501 3. The name of a namespace where we can find tag types whose names
502 match the function's parameter names.
504 4. The function signature.
509 Function signatures are described as one or two adjacent
510 parenthesized terms (a Boost.Preprocessor_ sequence_) describing
511 the function's parameters in the order in which they'd be expected
512 if passed positionally. Any required parameters must come first,
513 but the ``(required … )`` clause can be omitted when all the
514 parameters are optional.
516 .. _Boost.Preprocessor: ../../../preprocessor/index.html
523 Required parameters are given first—nested in a ``(required … )``
524 clause—as a series of two-element tuples describing each parameter
525 name and any requirements on the argument type. In this case there
526 is only a single required parameter, so there's just a single
531 (required **(graph, \*)** )
533 Since ``depth_first_search`` doesn't require any particular type
534 for its ``graph`` parameter, we use an asterix to indicate that
535 any type is allowed. Required parameters must always precede any
536 optional parameters in a signature, but if there are *no*
537 required parameters, the ``(required … )`` clause can be omitted
540 .. @example.prepend('''
541 #include <boost/parameter.hpp>
543 BOOST_PARAMETER_NAME(graph)
545 BOOST_PARAMETER_FUNCTION((void), f, tag,
548 .. @example.append(') {}')
556 Optional parameters—nested in an ``(optional … )`` clause—are given
557 as a series of adjacent *three*\ -element tuples describing the
558 parameter name, any requirements on the argument type, *and* and an
559 expression representing the parameter's default value:
564 (visitor, \*, boost::dfs_visitor<>())
565 (root_vertex, \*, \*vertices(graph).first)
566 (index_map, \*, get(boost::vertex_index,graph))
567 (in_out(color_map), \*,
568 default_color_map(num_vertices(graph), index_map) )**
571 .. @example.prepend('''
572 #include <boost/parameter.hpp>
576 int vertex_index = 0;
578 template <class T = int>
583 BOOST_PARAMETER_NAME(graph)
584 BOOST_PARAMETER_NAME(visitor)
585 BOOST_PARAMETER_NAME(root_vertex)
586 BOOST_PARAMETER_NAME(index_map)
587 BOOST_PARAMETER_NAME(color_map)
589 BOOST_PARAMETER_FUNCTION((void), f, tag,
590 (required (graph, *))
593 .. @example.append(') {}')
596 Handling “Out” Parameters
597 -------------------------
601 Within the function body, a parameter name such as ``visitor`` is
602 a *C++ reference*, bound either to an actual argument passed by
603 the caller or to the result of evaluating a default expression.
604 In most cases, parameter types are of the form ``T const&`` for
605 some ``T``. Parameters whose values are expected to be modified,
606 however, must be passed by reference to *non*\ -``const``. To
607 indicate that ``color_map`` is both read and written, we wrap
608 its name in ``in_out(…)``:
613 (visitor, \*, boost::dfs_visitor<>())
614 (root_vertex, \*, \*vertices(graph).first)
615 (index_map, \*, get(boost::vertex_index,graph))
616 (**in_out(color_map)**, \*,
617 default_color_map(num_vertices(graph), index_map) )
620 .. @example.prepend('''
621 #include <boost/parameter.hpp>
625 int vertex_index = 0;
627 template <class T = int>
632 BOOST_PARAMETER_NAME(graph)
634 BOOST_PARAMETER_NAME(visitor)
635 BOOST_PARAMETER_NAME(root_vertex)
636 BOOST_PARAMETER_NAME(index_map)
637 BOOST_PARAMETER_NAME(color_map)
639 BOOST_PARAMETER_FUNCTION((void), f, tag,
640 (required (graph, *))
643 .. @example.append(') {}')
646 If ``color_map`` were strictly going to be modified but not examined,
647 we could have written ``out(color_map)``. There is no functional
648 difference between ``out`` and ``in_out``; the library provides
649 both so you can make your interfaces more self-documenting.
654 When arguments are passed positionally (without the use of
655 keywords), they will be mapped onto parameters in the order the
656 parameters are given in the signature, so for example in this
659 graphs::depth_first_search(x, y);
663 ``x`` will always be interpreted as a graph and ``y`` will always
664 be interpreted as a visitor.
666 .. _sequence: http://boost-consulting.com/mplbook/preprocessor.html#sequences
668 Default Expression Evaluation
669 -----------------------------
673 Note that in our example, the value of the graph parameter is
674 used in the default expressions for ``root_vertex``,
675 ``index_map`` and ``color_map``.
679 (required (**graph**, \*) )
681 (visitor, \*, boost::dfs_visitor<>())
682 (root_vertex, \*, \*vertices(**graph**).first)
683 (index_map, \*, get(boost::vertex_index,\ **graph**))
684 (in_out(color_map), \*,
685 default_color_map(num_vertices(**graph**), index_map) )
690 A default expression is evaluated in the context of all preceding
691 parameters, so you can use any of their values by name.
695 A default expression is never evaluated—or even instantiated—if
696 an actual argument is passed for that parameter. We can actually
697 demonstrate that with our code so far by replacing the body of
698 ``depth_first_search`` with something that prints the arguments:
702 #include <boost/graph/depth_first_search.hpp> // for dfs_visitor
704 BOOST_PARAMETER_FUNCTION(
705 (void), depth_first_search, tag
706 *…signature goes here…*
709 std::cout << "graph=" << graph << std::endl;
710 std::cout << "visitor=" << visitor << std::endl;
711 std::cout << "root_vertex=" << root_vertex << std::endl;
712 std::cout << "index_map=" << index_map << std::endl;
713 std::cout << "color_map=" << color_map << std::endl;
718 depth_first_search(1, 2, 3, 4, 5);
721 "1", '2', _color_map = '5',
722 _index_map = "4", _root_vertex = "3");
725 Despite the fact that default expressions such as
726 ``vertices(graph).first`` are ill-formed for the given ``graph``
727 arguments, both calls will compile, and each one will print
728 exactly the same thing.
730 .. @example.prepend('''
731 #include <boost/parameter.hpp>
734 BOOST_PARAMETER_NAME(graph)
735 BOOST_PARAMETER_NAME(visitor)
736 BOOST_PARAMETER_NAME(root_vertex)
737 BOOST_PARAMETER_NAME(index_map)
738 BOOST_PARAMETER_NAME(color_map)''')
740 .. @example.replace_emphasis('''
751 Signature Matching and Overloading
752 ----------------------------------
754 In fact, the function signature is so general that any call to
755 ``depth_first_search`` with fewer than five arguments will match
756 our function, provided we pass *something* for the required
757 ``graph`` parameter. That might not seem to be a problem at first;
758 after all, if the arguments don't match the requirements imposed by
759 the implementation of ``depth_first_search``, a compilation error
760 will occur later, when its body is instantiated.
762 There are at least three problems with very general function
765 1. By the time our ``depth_first_search`` is instantiated, it has
766 been selected as the best matching overload. Some other
767 ``depth_first_search`` overload might've worked had it been
768 chosen instead. By the time we see a compilation error, there's
769 no chance to change that decision.
771 2. Even if there are no overloads, error messages generated at
772 instantiation time usually expose users to confusing
773 implementation details. For example, users might see references
774 to names generated by ``BOOST_PARAMETER_FUNCTION`` such as
775 ``graphs::detail::depth_first_search_with_named_params`` (or
776 worse—think of the kinds of errors you get from your STL
777 implementation when you make a mistake). [#ConceptCpp]_
779 3. The problems with exposing such permissive function template
780 signatures have been the subject of much discussion, especially
781 in the presence of `unqualified calls`__. If all we want is to
782 avoid unintentional argument-dependent lookup (ADL), we can
783 isolate ``depth_first_search`` in a namespace containing no
784 types [#using]_, but suppose we *want* it to found via ADL?
786 __ http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#225
788 It's usually a good idea to prevent functions from being considered
789 for overload resolution when the passed argument types aren't
790 appropriate. The library already does this when the required
791 ``graph`` parameter is not supplied, but we're not likely to see a
792 depth first search that doesn't take a graph to operate on.
793 Suppose, instead, that we found a different depth first search
794 algorithm that could work on graphs that don't model
795 |IncidenceGraph|_? If we just added a simple overload,
796 it would be ambiguous::
799 BOOST_PARAMETER_FUNCTION(
800 (void), depth_first_search, (tag), (required (graph,*))( … ))
802 // new algorithm implementation
808 depth_first_search(boost::adjacency_list<>(), 2, "hello");
812 Adding Type Requirements
813 ........................
815 We really don't want the compiler to consider the original version
816 of ``depth_first_search`` because the ``root_vertex`` argument,
817 ``"hello"``, doesn't meet the requirement__ that it match the
818 ``graph`` parameter's vertex descriptor type. Instead, this call
819 should just invoke our new overload. To take the original
820 ``depth_first_search`` overload out of contention, we need to tell
821 the library about this requirement by replacing the ``*`` element
822 of the signature with the required type, in parentheses:
824 __ `parameter table`_
829 **(typename boost::graph_traits<graph_type>::vertex_descriptor)**,
830 \*vertices(graph).first)
834 Now the original ``depth_first_search`` will only be called when
835 the ``root_vertex`` argument can be converted to the graph's vertex
836 descriptor type, and our example that *was* ambiguous will smoothly
837 call the new overload.
839 .. Note:: The *type* of the ``graph`` argument is available in the
840 signature—and in the function body—as ``graph_type``. In
841 general, to access the type of any parameter *foo*, write *foo*\
845 Predicate Requirements
846 ......................
848 The requirements on other arguments are a bit more interesting than
849 those on ``root_vertex``; they can't be described in terms of simple
850 type matching. Instead, they must be described in terms of `MPL
851 Metafunctions`__. There's no space to give a complete description
852 of metafunctions or of graph library details here, but we'll show
853 you the complete signature with maximal checking, just to give you
854 a feel for how it's done. Each predicate metafunction is enclosed
855 in parentheses *and preceded by an asterix*, as follows:
859 // We first need to define a few metafunction that we use in the
863 struct traversal_category
865 typedef typename boost::graph_traits<G>::traversal_category type;
869 struct vertex_descriptor
871 typedef typename boost::graph_traits<G>::vertex_descriptor type;
877 typedef typename boost::property_traits<G>::value_type type;
883 typedef typename boost::property_traits<G>::key_type type;
886 template<class Size, class IndexMap>
887 boost::iterator_property_map<
888 boost::default_color_type\*, IndexMap
889 , boost::default_color_type, boost::default_color_type&
891 default_color_map(Size num_vertices, IndexMap const& index_map)
893 std::vector<boost::default_color_type> colors(num_vertices);
897 BOOST_PARAMETER_FUNCTION(
898 (void), depth_first_search, graphs
902 , **\ \*(boost::mpl::and_<
903 boost::is_convertible<
904 traversal_category<_>, boost::incidence_graph_tag
906 , boost::is_convertible<
907 traversal_category<_>, boost::vertex_list_graph_tag
912 (visitor, \*, boost::dfs_visitor<>()) // not checkable
915 , (vertex_descriptor<graphs::graph::_>)
916 , \*vertices(graph).first)
919 , **\ \*(boost::mpl::and_<
920 boost::is_integral<value_type<_> >
922 vertex_descriptor<graphs::graph::_>, key_type<_>
925 , get(boost::vertex_index,graph))
928 , **\ \*(boost::is_same<
929 vertex_descriptor<graphs::graph::_>, key_type<_>
931 , default_color_map(num_vertices(graph), index_map) )
935 .. @example.prepend('''
936 #include <boost/parameter.hpp>
937 #include <boost/graph/adjacency_list.hpp>
938 #include <boost/graph/depth_first_search.hpp>
940 BOOST_PARAMETER_NAME((_graph, graphs) graph)
941 BOOST_PARAMETER_NAME((_visitor, graphs) visitor)
942 BOOST_PARAMETER_NAME((_root_vertex, graphs) root_vertex)
943 BOOST_PARAMETER_NAME((_index_map, graphs) index_map)
944 BOOST_PARAMETER_NAME((_color_map, graphs) color_map)
949 .. @example.append('''
954 typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS> G;
956 enum {u, v, w, x, y, z, N};
957 typedef std::pair<int, int> E;
958 E edges[] = {E(u, v), E(u, x), E(x, v), E(y, x), E(v, y), E(w, y),
960 G g(edges, edges + sizeof(edges) / sizeof(E), N);
962 depth_first_search(g);
963 depth_first_search(g, _root_vertex = (int)x);
969 Note the use of the nested `tag::_`. This is a shortcut for::
971 value_type<boost::mpl::_2, tag>
975 Intended to be used to access preceding arguments types in the
978 __ ../../../mpl/doc/refmanual/metafunction.html
980 We acknowledge that this signature is pretty hairy looking.
981 Fortunately, it usually isn't necessary to so completely encode the
982 type requirements on arguments to generic functions. However, it
983 is usally worth the effort to do so: your code will be more
984 self-documenting and will often provide a better user experience.
985 You'll also have an easier transition to an upcoming C++ standard
986 with `language support for concepts`__.
993 To illustrate deduced parameter support we'll have to leave behind
994 our example from the Graph library. Instead, consider the example
995 of the |def|_ function from Boost.Python_. Its signature is
999 class Function, Class KeywordExpression, class CallPolicies
1002 // Required parameters
1003 char const* name, Function func
1005 // Optional, deduced parameters
1006 , char const* docstring = ""
1007 , KeywordExpression keywords = no_keywords()
1008 , CallPolicies policies = default_call_policies()
1013 Try not to be too distracted by the use of the term “keywords” in
1014 this example: although it means something analogous in Boost.Python
1015 to what it means in the Parameter library, for the purposes of this
1016 exercise you can think of it as being completely different.
1018 When calling ``def``, only two arguments are required. The
1019 association between any additional arguments and their parameters
1020 can be determined by the types of the arguments actually passed, so
1021 the caller is neither required to remember argument positions or
1022 explicitly specify parameter names for those arguments. To
1023 generate this interface using ``BOOST_PARAMETER_FUNCTION``, we need
1024 only enclose the deduced parameters in a ``(deduced …)`` clause, as
1029 namespace mpl = boost::mpl;
1031 BOOST_PARAMETER_FUNCTION(
1034 (required (name,(char const\*)) (func,\*) ) // nondeduced
1038 (docstring, (char const\*), "")
1041 , \*(is_keyword_expression<mpl::_>) // see [#is_keyword_expression]_
1047 boost::is_convertible<mpl::_, char const\*>
1048 , is_keyword_expression<mpl::_> // see [#is_keyword_expression]_
1051 , default_call_policies()
1060 .. @example.replace_emphasis('')
1062 .. @example.prepend('''
1063 #include <boost/parameter.hpp>
1065 BOOST_PARAMETER_NAME(name)
1066 BOOST_PARAMETER_NAME(func)
1067 BOOST_PARAMETER_NAME(docstring)
1068 BOOST_PARAMETER_NAME(keywords)
1069 BOOST_PARAMETER_NAME(policies)
1071 struct default_call_policies
1081 struct is_keyword_expression
1082 : boost::mpl::false_
1086 struct is_keyword_expression<keywords>
1090 default_call_policies some_policies;
1097 .. Admonition:: Syntax Note
1099 A ``(deduced …)`` clause always contains a ``(required …)``
1100 and/or an ``(optional …)`` subclause, and must follow any
1101 ``(required …)`` or ``(optional …)`` clauses indicating
1102 nondeduced parameters at the outer level.
1104 With the declaration above, the following two calls are equivalent:
1108 def("f", &f, **some_policies**, **"Documentation for f"**);
1109 def("f", &f, **"Documentation for f"**, **some_policies**);
1111 .. @example.prepend('''
1115 If the user wants to pass a ``policies`` argument that was also,
1116 for some reason, convertible to ``char const*``, she can always
1117 specify the parameter name explicitly, as follows:
1123 , **_policies = some_policies**, "Documentation for f");
1125 .. @example.append('}')
1126 .. @test('compile', howmany='all')
1128 .. _Boost.Python: ../../../python/doc/index.html
1129 .. |def| replace:: ``def``
1130 .. _def: ../../../python/doc/v2/def.html
1132 ----------------------------------
1133 Parameter-Enabled Member Functions
1134 ----------------------------------
1137 The ``BOOST_PARAMETER_MEMBER_FUNCTION`` and
1138 ``BOOST_PARAMETER_CONST_MEMBER_FUNCTION`` macros accept exactly the
1139 same arguments as ``BOOST_PARAMETER_FUNCTION``, but are designed to
1140 be used within the body of a class::
1142 BOOST_PARAMETER_NAME(arg1)
1143 BOOST_PARAMETER_NAME(arg2)
1147 BOOST_PARAMETER_CONST_MEMBER_FUNCTION(
1148 (void), call, tag, (required (arg1,(int))(arg2,(int))))
1150 std::cout << arg1 << ", " << arg2 << std::endl;
1154 .. @example.prepend('''
1155 #include <boost/parameter.hpp>
1157 using namespace boost::parameter;
1162 These macros don't directly allow a function's interface to be
1163 separated from its implementation, but you can always forward
1164 arguments on to a separate implementation function::
1168 BOOST_PARAMETER_CONST_MEMBER_FUNCTION(
1169 (void), call, tag, (required (arg1,(int))(arg2,(int))))
1171 call_impl(arg1,arg2);
1174 void call_impl(int, int); // implemented elsewhere.
1177 .. @example.prepend('''
1178 #include <boost/parameter.hpp>
1180 BOOST_PARAMETER_NAME(arg1)
1181 BOOST_PARAMETER_NAME(arg2)
1182 using namespace boost::parameter;
1187 Static Member Functions
1188 =======================
1190 To expose a static member function, simply insert the keyword
1191 “``static``” before the function name:
1195 BOOST_PARAMETER_NAME(arg1)
1199 BOOST_PARAMETER_MEMBER_FUNCTION(
1200 (void), **static** f, tag, (optional (arg1,(int),0)))
1202 std::cout << arg1 << std::endl;
1206 .. @example.prepend('''
1207 #include <boost/parameter.hpp>
1209 using namespace boost::parameter;
1215 ------------------------------
1216 Parameter-Enabled Constructors
1217 ------------------------------
1219 The lack of a “delegating constructor”
1221 (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf)
1222 limits somewhat the quality of interface this library can provide
1223 for defining parameter-enabled constructors. The usual workaround
1224 for a lack of constructor delegation applies: one must factor the
1225 common logic into a base class.
1227 Let's build a parameter-enabled constructor that simply prints its
1228 arguments. The first step is to write a base class whose
1229 constructor accepts a single argument known as an |ArgumentPack|_:
1230 a bundle of references to the actual arguments, tagged with their
1231 keywords. The values of the actual arguments are extracted from
1232 the |ArgumentPack| by *indexing* it with keyword objects::
1234 BOOST_PARAMETER_NAME(name)
1235 BOOST_PARAMETER_NAME(index)
1239 template <class ArgumentPack>
1240 myclass_impl(ArgumentPack const& args)
1242 std::cout << "name = " << args[_name]
1243 << "; index = " << args[_index | 42]
1248 .. @example.prepend('''
1249 #include <boost/parameter.hpp>
1250 #include <iostream>''')
1252 Note that the bitwise or (“\ ``|``\ ”) operator has a special
1253 meaning when applied to keyword objects that are passed to an
1254 |ArgumentPack|\ 's indexing operator: it is used to indicate a
1255 default value. In this case if there is no ``index`` parameter in
1256 the |ArgumentPack|, ``42`` will be used instead.
1258 Now we are ready to write the parameter-enabled constructor
1261 struct myclass : myclass_impl
1263 BOOST_PARAMETER_CONSTRUCTOR(
1264 myclass, (myclass_impl), tag
1265 , (required (name,*)) (optional (index,*))) // no semicolon
1268 Since we have supplied a default value for ``index`` but not for
1269 ``name``, only ``name`` is required. We can exercise our new
1270 interface as follows::
1272 myclass x("bob", 3); // positional
1273 myclass y(_index = 12, _name = "sally"); // named
1274 myclass z("june"); // positional/defaulted
1276 .. @example.wrap('int main() {', '}')
1277 .. @test('run', howmany='all')
1279 For more on |ArgumentPack| manipulation, see the `Advanced Topics`_
1282 ---------------------------------
1283 Parameter-Enabled Class Templates
1284 ---------------------------------
1286 In this section we'll use Boost.Parameter to build Boost.Python_\
1287 's `class_`_ template, whose “signature” is:
1292 ValueType, BaseList = bases<>
1293 , HeldType = ValueType, Copyable = void
1299 Only the first argument, ``ValueType``, is required.
1301 .. _class_: http://www.boost.org/libs/python/doc/v2/class.html#class_-spec
1303 Named Template Parameters
1304 =========================
1306 First, we'll build an interface that allows users to pass arguments
1307 positionally or by name:
1311 struct B { virtual ~B() = 0; };
1312 struct D : B { ~D(); };
1315 **class_type<B>**, **copyable<boost::noncopyable>**
1319 **D**, **held_type<std::auto_ptr<D> >**, **base_list<bases<B> >**
1327 The first step is to define keywords for each template parameter::
1329 namespace boost { namespace python {
1331 BOOST_PARAMETER_TEMPLATE_KEYWORD(class_type)
1332 BOOST_PARAMETER_TEMPLATE_KEYWORD(base_list)
1333 BOOST_PARAMETER_TEMPLATE_KEYWORD(held_type)
1334 BOOST_PARAMETER_TEMPLATE_KEYWORD(copyable)
1338 .. @example.prepend('#include <boost/parameter.hpp>')
1341 The declaration of the ``class_type`` keyword you see here is
1344 namespace boost { namespace python {
1346 namespace tag { struct class_type; } // keyword tag type
1349 : parameter::template_keyword<tag::class_type,T>
1354 .. @example.prepend('#include <boost/parameter.hpp>')
1357 It defines a keyword tag type named ``tag::class_type`` and a
1358 *parameter passing template* named ``class_type``.
1360 Class Template Skeleton
1361 -----------------------
1363 The next step is to define the skeleton of our class template,
1364 which has three optional parameters. Because the user may pass
1365 arguments in any order, we don't know the actual identities of
1366 these parameters, so it would be premature to use descriptive names
1367 or write out the actual default values for any of them. Instead,
1368 we'll give them generic names and use the special type
1369 ``boost::parameter::void_`` as a default:
1373 namespace boost { namespace python {
1377 , class A1 = parameter::void\_
1378 , class A2 = parameter::void\_
1379 , class A3 = parameter::void\_
1388 .. @example.prepend('#include <boost/parameter.hpp>')
1389 .. @example.replace_emphasis('')
1392 Class Template Signatures
1393 -------------------------
1395 Next, we need to build a type, known as a |ParameterSpec|_,
1396 describing the “signature” of ``boost::python::class_``. A
1397 |ParameterSpec|_ enumerates the required and optional parameters in
1398 their positional order, along with any type requirements (note that
1399 it does *not* specify defaults -- those will be dealt with
1402 namespace boost { namespace python {
1404 using boost::mpl::_;
1406 typedef parameter::parameters<
1407 required<tag::class_type, boost::is_class<_> >
1408 , parameter::optional<tag::base_list, mpl::is_sequence<_> >
1409 , parameter::optional<tag::held_type>
1410 , parameter::optional<tag::copyable>
1415 .. @example.prepend('''
1416 #include <boost/parameter.hpp>
1417 #include <boost/mpl/is_sequence.hpp>
1418 #include <boost/noncopyable.hpp>
1419 #include <boost/type_traits/is_class.hpp>
1422 using namespace boost::parameter;
1424 namespace boost { namespace python {
1426 BOOST_PARAMETER_TEMPLATE_KEYWORD(class_type)
1427 BOOST_PARAMETER_TEMPLATE_KEYWORD(base_list)
1428 BOOST_PARAMETER_TEMPLATE_KEYWORD(held_type)
1429 BOOST_PARAMETER_TEMPLATE_KEYWORD(copyable)
1431 template <class B = int>
1437 .. |ParameterSpec| replace:: :concept:`ParameterSpec`
1439 .. _ParameterSpec: reference.html#parameterspec
1443 Argument Packs and Parameter Extraction
1444 ---------------------------------------
1446 Next, within the body of ``class_`` , we use the |ParameterSpec|\ 's
1447 nested ``::bind< … >`` template to bundle the actual arguments into an
1448 |ArgumentPack|_ type, and then use the library's ``value_type< … >``
1449 metafunction to extract “logical parameters”. ``value_type< … >`` is
1450 a lot like ``binding< … >``, but no reference is added to the actual
1451 argument type. Note that defaults are specified by passing it an
1452 optional third argument::
1454 namespace boost { namespace python {
1458 , class A1 = parameter::void_
1459 , class A2 = parameter::void_
1460 , class A3 = parameter::void_
1464 // Create ArgumentPack
1466 class_signature::bind<A0,A1,A2,A3>::type
1469 // Extract first logical parameter.
1470 typedef typename parameter::value_type<
1471 args, tag::class_type>::type class_type;
1473 typedef typename parameter::value_type<
1474 args, tag::base_list, bases<> >::type base_list;
1476 typedef typename parameter::value_type<
1477 args, tag::held_type, class_type>::type held_type;
1479 typedef typename parameter::value_type<
1480 args, tag::copyable, void>::type copyable;
1485 .. |ArgumentPack| replace:: :concept:`ArgumentPack`
1486 .. _ArgumentPack: reference.html#argumentpack
1488 Exercising the Code So Far
1489 ==========================
1493 Revisiting our original examples, ::
1495 typedef boost::python::class_<
1496 class_type<B>, copyable<boost::noncopyable>
1499 typedef boost::python::class_<
1500 D, held_type<std::auto_ptr<D> >, base_list<bases<B> >
1503 .. @example.prepend('''
1504 using boost::python::class_type;
1505 using boost::python::copyable;
1506 using boost::python::held_type;
1507 using boost::python::base_list;
1508 using boost::python::bases;
1513 we can now examine the intended parameters::
1515 BOOST_MPL_ASSERT((boost::is_same<c1::class_type, B>));
1516 BOOST_MPL_ASSERT((boost::is_same<c1::base_list, bases<> >));
1517 BOOST_MPL_ASSERT((boost::is_same<c1::held_type, B>));
1519 boost::is_same<c1::copyable, boost::noncopyable>
1522 BOOST_MPL_ASSERT((boost::is_same<c2::class_type, D>));
1523 BOOST_MPL_ASSERT((boost::is_same<c2::base_list, bases<B> >));
1525 boost::is_same<c2::held_type, std::auto_ptr<D> >
1527 BOOST_MPL_ASSERT((boost::is_same<c2::copyable, void>));
1529 .. @test('compile', howmany='all')
1531 Deduced Template Parameters
1532 ===========================
1534 To apply a deduced parameter interface here, we need only make the
1535 type requirements a bit tighter so the ``held_type`` and
1536 ``copyable`` parameters can be crisply distinguished from the
1537 others. Boost.Python_ does this by requiring that ``base_list`` be
1538 a specialization of its ``bases< … >`` template (as opposed to
1539 being any old MPL sequence) and by requiring that ``copyable``, if
1540 explicitly supplied, be ``boost::noncopyable``. One easy way of
1541 identifying specializations of ``bases< … >`` is to derive them all
1542 from the same class, as an implementation detail:
1546 namespace boost { namespace python {
1548 namespace detail { struct bases_base {}; }
1550 template <class A0 = void, class A1 = void, class A2 = void *…* >
1551 struct bases **: detail::bases_base**
1556 .. @example.replace_emphasis('')
1557 .. @example.prepend('''
1558 #include <boost/parameter.hpp>
1559 #include <boost/mpl/is_sequence.hpp>
1560 #include <boost/noncopyable.hpp>
1563 using namespace boost::parameter;
1564 using boost::mpl::_;
1566 namespace boost { namespace python {
1568 BOOST_PARAMETER_TEMPLATE_KEYWORD(class_type)
1569 BOOST_PARAMETER_TEMPLATE_KEYWORD(base_list)
1570 BOOST_PARAMETER_TEMPLATE_KEYWORD(held_type)
1571 BOOST_PARAMETER_TEMPLATE_KEYWORD(copyable)
1575 Now we can rewrite our signature to make all three optional
1576 parameters deducible::
1578 typedef parameter::parameters<
1579 required<tag::class_type, is_class<_> >
1581 , parameter::optional<
1582 deduced<tag::base_list>
1583 , is_base_and_derived<detail::bases_base,_>
1586 , parameter::optional<
1587 deduced<tag::held_type>
1590 is_base_and_derived<detail::bases_base,_>
1591 , is_same<noncopyable,_>
1596 , parameter::optional<deduced<tag::copyable>, is_same<noncopyable,_> >
1600 .. @example.prepend('''
1601 #include <boost/type_traits/is_class.hpp>
1602 namespace boost { namespace python {''')
1604 .. @example.append('''
1607 , class A1 = parameter::void_
1608 , class A2 = parameter::void_
1609 , class A3 = parameter::void_
1613 // Create ArgumentPack
1615 class_signature::bind<A0,A1,A2,A3>::type
1618 // Extract first logical parameter.
1619 typedef typename parameter::value_type<
1620 args, tag::class_type>::type class_type;
1622 typedef typename parameter::value_type<
1623 args, tag::base_list, bases<> >::type base_list;
1625 typedef typename parameter::value_type<
1626 args, tag::held_type, class_type>::type held_type;
1628 typedef typename parameter::value_type<
1629 args, tag::copyable, void>::type copyable;
1634 It may seem like we've added a great deal of complexity, but the
1635 benefits to our users are greater. Our original examples can now
1636 be written without explicit parameter names:
1640 typedef boost::python::class_<**B**, **boost::noncopyable**> c1;
1642 typedef boost::python::class_<**D**, **std::auto_ptr<D>**, **bases<B>** > c2;
1644 .. @example.prepend('''
1648 using boost::python::bases;''')
1650 .. @example.append('''
1651 BOOST_MPL_ASSERT((boost::is_same<c1::class_type, B>));
1652 BOOST_MPL_ASSERT((boost::is_same<c1::base_list, bases<> >));
1653 BOOST_MPL_ASSERT((boost::is_same<c1::held_type, B>));
1655 boost::is_same<c1::copyable, boost::noncopyable>
1658 BOOST_MPL_ASSERT((boost::is_same<c2::class_type, D>));
1659 BOOST_MPL_ASSERT((boost::is_same<c2::base_list, bases<B> >));
1661 boost::is_same<c2::held_type, std::auto_ptr<D> >
1663 BOOST_MPL_ASSERT((boost::is_same<c2::copyable, void>));''')
1665 .. @test('compile', howmany='all')
1671 At this point, you should have a good grasp of the basics. In this
1672 section we'll cover some more esoteric uses of the library.
1674 -------------------------
1675 Fine-Grained Name Control
1676 -------------------------
1678 If you don't like the leading-underscore naming convention used
1679 to refer to keyword objects, or you need the name ``tag`` for
1680 something other than the keyword type namespace, there's another
1681 way to use ``BOOST_PARAMETER_NAME``:
1685 BOOST_PARAMETER_NAME(\ **(**\ *object-name*\ **,** *tag-namespace*\ **)** *parameter-name*\ )
1689 Here is a usage example:
1693 BOOST_PARAMETER_NAME((**pass_foo**, **keywords**) **foo**)
1695 BOOST_PARAMETER_FUNCTION(
1697 **keywords**, (required (**foo**, \*)))
1702 int x = f(**pass_foo** = 41);
1704 .. @example.prepend('#include <boost/parameter.hpp>')
1705 .. @example.append('''
1710 Before you use this more verbose form, however, please read the
1711 section on `best practices for keyword object naming`__.
1713 __ `Keyword Naming`_
1715 -----------------------
1716 More |ArgumentPack|\ s
1717 -----------------------
1719 We've already seen |ArgumentPack|\ s when we looked at
1720 `parameter-enabled constructors`_ and `class templates`__. As you
1721 might have guessed, |ArgumentPack|\ s actually lie at the heart of
1722 everything this library does; in this section we'll examine ways to
1723 build and manipulate them more effectively.
1727 Building |ArgumentPack|\ s
1728 ==========================
1730 The simplest |ArgumentPack| is the result of assigning into a
1733 BOOST_PARAMETER_NAME(index)
1735 template <class ArgumentPack>
1736 int print_index(ArgumentPack const& args)
1738 std::cout << "index = " << args[_index] << std::endl;
1742 int x = print_index(_index = 3); // prints "index = 3"
1744 .. @example.prepend('''
1745 #include <boost/parameter.hpp>
1746 #include <iostream>''')
1748 Also, |ArgumentPack|\ s can be composed using the comma operator.
1749 The extra parentheses below are used to prevent the compiler from
1750 seeing two separate arguments to ``print_name_and_index``::
1752 BOOST_PARAMETER_NAME(name)
1754 template <class ArgumentPack>
1755 int print_name_and_index(ArgumentPack const& args)
1757 std::cout << "name = " << args[_name] << "; ";
1758 return print_index(args);
1761 int y = print_name_and_index((_index = 3, _name = "jones"));
1763 To build an |ArgumentPack| with positional arguments, we can use a
1764 |ParameterSpec|_. As introduced described in the section on `Class
1765 Template Signatures`_, a |ParameterSpec| describes the positional
1766 order of parameters and any associated type requirements. Just as
1767 we can build an |ArgumentPack| *type* with its nested ``::bind< …
1768 >`` template, we can build an |ArgumentPack| *object* by invoking
1769 its function call operator:
1773 parameter::parameters<
1774 required<tag::\ name, is_convertible<_,char const*> >
1775 , optional<tag::\ index, is_convertible<_,int> >
1778 char const sam[] = "sam";
1781 int z0 = print_name_and_index( **spec(**\ sam, twelve\ **)** );
1783 int z1 = print_name_and_index(
1784 **spec(**\ _index=12, _name="sam"\ **)**
1787 .. @example.prepend('''
1788 namespace parameter = boost::parameter;
1789 using parameter::required;
1790 using parameter::optional;
1791 using boost::is_convertible;
1792 using boost::mpl::_;''')
1794 .. @example.append('''
1798 .. @test('run', howmany='all')
1800 Note that because of the `forwarding problem`_, ``parameter::parameters::operator()``
1801 can't accept non-const rvalues.
1803 .. _`forwarding problem`: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm
1805 Extracting Parameter Types
1806 ==========================
1808 If we want to know the types of the arguments passed to
1809 ``print_name_and_index``, we have a couple of options. The
1810 simplest and least error-prone approach is to forward them to a
1811 function template and allow *it* to do type deduction::
1813 BOOST_PARAMETER_NAME(name)
1814 BOOST_PARAMETER_NAME(index)
1816 template <class Name, class Index>
1817 int deduce_arg_types_impl(Name& name, Index& index)
1819 Name& n2 = name; // we know the types
1824 template <class ArgumentPack>
1825 int deduce_arg_types(ArgumentPack const& args)
1827 return deduce_arg_types_impl(args[_name], args[_index|42]);
1830 .. @example.prepend('''
1831 #include <boost/parameter.hpp>
1832 #include <cassert>''')
1834 .. @example.append('''
1835 int a1 = deduce_arg_types((_name = "foo"));
1836 int a2 = deduce_arg_types((_name = "foo", _index = 3));
1846 Occasionally one needs to deduce argument types without an extra
1847 layer of function call. For example, suppose we wanted to return
1848 twice the value of the ``index`` parameter? In that
1849 case we can use the ``value_type< … >`` metafunction introduced
1852 BOOST_PARAMETER_NAME(index)
1854 template <class ArgumentPack>
1855 typename parameter::value_type<ArgumentPack, tag::index, int>::type
1856 twice_index(ArgumentPack const& args)
1858 return 2 * args[_index|42];
1861 int six = twice_index(_index = 3);
1863 .. @example.prepend('''
1864 #include <boost/parameter.hpp>
1865 #include <boost/type_traits/remove_reference.hpp>
1868 namespace parameter = boost::parameter;
1871 .. @example.append('''
1877 .. @test('run', howmany='all')
1879 Note that if we had used ``binding< … >`` rather than ``value_type< …
1880 >``, we would end up returning a reference to the temporary created in
1881 the ``2 * …`` expression.
1885 Lazy Default Computation
1886 ========================
1888 When a default value is expensive to compute, it would be
1889 preferable to avoid it until we're sure it's absolutely necessary.
1890 ``BOOST_PARAMETER_FUNCTION`` takes care of that problem for us, but
1891 when using |ArgumentPack|\ s explicitly, we need a tool other than
1894 BOOST_PARAMETER_NAME(s1)
1895 BOOST_PARAMETER_NAME(s2)
1896 BOOST_PARAMETER_NAME(s3)
1898 template <class ArgumentPack>
1899 std::string f(ArgumentPack const& args)
1901 std::string const& s1 = args[_s1];
1902 std::string const& s2 = args[_s2];
1903 typename parameter::binding<
1904 ArgumentPack,tag::s3,std::string
1905 >::type s3 = args[_s3|(s1+s2)]; // always constructs s1+s2
1909 std::string x = f((_s1="hello,", _s2=" world", _s3="hi world"));
1911 .. @example.prepend('''
1912 #include <boost/parameter.hpp>
1915 namespace parameter = boost::parameter;''')
1917 .. @example.append('''
1923 In the example above, the string ``"hello, world"`` is constructed
1924 despite the fact that the user passed us a value for ``s3``. To
1925 remedy that, we can compute the default value *lazily* (that is,
1926 only on demand), by using ``boost::bind()`` to create a function
1929 .. danielw: I'm leaving the text below in the source, because we might
1930 .. want to change back to it after 1.34, and if I remove it now we
1931 .. might forget about it.
1933 .. by combining the logical-or (“``||``”) operator
1934 .. with a function object built by the Boost Lambda_ library: [#bind]_
1938 typename parameter::binding<
1939 ArgumentPack, tag::s3, std::string
1940 >::type s3 = args[_s3
1941 **|| boost::bind(std::plus<std::string>(), boost::ref(s1), boost::ref(s2))** ];
1943 .. @example.prepend('''
1944 #include <boost/bind.hpp>
1945 #include <boost/ref.hpp>
1946 #include <boost/parameter.hpp>
1948 #include <functional>
1950 namespace parameter = boost::parameter;
1952 BOOST_PARAMETER_NAME(s1)
1953 BOOST_PARAMETER_NAME(s2)
1954 BOOST_PARAMETER_NAME(s3)
1956 template <class ArgumentPack>
1957 std::string f(ArgumentPack const& args)
1959 std::string const& s1 = args[_s1];
1960 std::string const& s2 = args[_s2];''')
1962 .. @example.append('''
1966 std::string x = f((_s1="hello,", _s2=" world", _s3="hi world"));
1973 .. .. _Lambda: ../../../lambda/index.html
1975 .. sidebar:: Mnemonics
1977 To remember the difference between ``|`` and ``||``, recall that
1978 ``||`` normally uses short-circuit evaluation: its second
1979 argument is only evaluated if its first argument is ``false``.
1980 Similarly, in ``color_map[param||f]``, ``f`` is only invoked if
1981 no ``color_map`` argument was supplied.
1983 The expression ``bind(std::plus<std::string>(), ref(s1), ref(s2))`` yields
1984 a *function object* that, when invoked, adds the two strings together.
1985 That function will only be invoked if no ``s3`` argument is supplied by
1988 .. The expression ``lambda::var(s1)+lambda::var(s2)`` yields a
1989 .. *function object* that, when invoked, adds the two strings
1990 .. together. That function will only be invoked if no ``s3`` argument
1991 .. is supplied by the caller.
1997 By now you should have a fairly good idea of how to use the
1998 Parameter library. This section points out a few more-marginal
1999 issues that will help you use the library more effectively.
2005 ``BOOST_PARAMETER_NAME`` prepends a leading underscore to the names
2006 of all our keyword objects in order to avoid the following
2013 namespace tag { struct name; struct age; }
2015 namespace // unnamed
2017 boost::parameter::keyword<tag::name>& **name**
2018 = boost::parameter::keyword<tag::name>::instance;
2019 boost::parameter::keyword<tag::age>& **age**
2020 = boost::parameter::keyword<tag::age>::instance;
2023 BOOST_PARAMETER_FUNCTION(
2024 (void), g, tag, (optional (name, \*, "bob")(age, \*, 42)))
2026 std::cout << name << ":" << age;
2036 g(**age** = 3); // whoops!
2042 Although in the case above, the user was trying to pass the value
2043 ``3`` as the ``age`` parameter to ``g``, what happened instead
2044 was that ``f``\ 's ``age`` argument got reassigned the value 3,
2045 and was then passed as a positional argument to ``g``. Since
2046 ``g``'s first positional parameter is ``name``, the default value
2047 for ``age`` is used, and g prints ``3:42``. Our leading
2048 underscore naming convention that makes this problem less likely
2051 In this particular case, the problem could have been detected if
2052 f's ``age`` parameter had been made ``const``, which is always a
2053 good idea whenever possible. Finally, we recommend that you use
2054 an enclosing namespace for all your code, but particularly for
2055 names with leading underscores. If we were to leave out the
2056 ``people`` namespace above, names in the global namespace
2057 beginning with leading underscores—which are reserved to your C++
2058 compiler—might become irretrievably ambiguous with those in our
2065 In our examples we've always declared keyword objects in (an
2066 unnamed namespace within) the same namespace as the
2067 Boost.Parameter-enabled functions using those keywords:
2073 **BOOST_PARAMETER_NAME(name)
2074 BOOST_PARAMETER_NAME(index)**
2076 BOOST_PARAMETER_FUNCTION(
2078 (optional (name,*,"bob")(index,(int),1))
2081 std::cout << name << ":" << index << std::endl;
2086 .. @example.prepend('''
2087 #include <boost/parameter.hpp>
2088 #include <iostream>''')
2089 .. @namespace_setup = str(example)
2092 Users of these functions have a few choices:
2094 1. Full qualification:
2098 int x = **lib::**\ f(**lib::**\ _name = "jill", **lib::**\ _index = 1);
2100 This approach is more verbose than many users would like.
2102 .. @example.prepend(namespace_setup)
2103 .. @example.append('int main() {}')
2106 2. Make keyword objects available through
2107 *using-declarations*:
2112 using lib::_index;**
2114 int x = lib::f(_name = "jill", _index = 1);
2116 This version is much better at the actual call site, but the
2117 *using-declarations* themselves can be verbose and hard-to
2120 .. @example.prepend(namespace_setup)
2121 .. @example.append('int main() {}')
2124 3. Bring in the entire namespace with a *using-directive*:
2128 **using namespace lib;**
2129 int x = **f**\ (_name = "jill", _index = 3);
2131 This option is convenient, but it indiscriminately makes the
2132 *entire* contents of ``lib`` available without qualification.
2134 .. @example.prepend(namespace_setup)
2135 .. @example.append('int main() {}')
2138 If we add an additional namespace around keyword declarations,
2139 though, we can give users more control:
2145 **namespace keywords
2147 BOOST_PARAMETER_NAME(name)
2148 BOOST_PARAMETER_NAME(index)
2151 BOOST_PARAMETER_FUNCTION(
2152 (int), f, **keywords::**\ tag,
2153 (optional (name,*,"bob")(index,(int),1))
2156 std::cout << name << ":" << index << std::endl;
2161 .. @example.prepend('''
2162 #include <boost/parameter.hpp>
2163 #include <iostream>''')
2165 Now users need only a single *using-directive* to bring in just the
2166 names of all keywords associated with ``lib``:
2170 **using namespace lib::keywords;**
2171 int y = lib::f(_name = "bob", _index = 2);
2173 .. @example.append('int main() {}')
2174 .. @test('run', howmany='all')
2180 The interface idioms enabled by Boost.Parameter are completely new
2181 (to C++), and as such are not served by pre-existing documentation
2184 .. Note:: This space is empty because we haven't settled on any
2185 best practices yet. We'd be very pleased to link to your
2186 documentation if you've got a style that you think is worth
2189 ============================
2190 Portability Considerations
2191 ============================
2193 Use the `regression test results`_ for the latest Boost release of
2194 the Parameter library to see how it fares on your favorite
2195 compiler. Additionally, you may need to be aware of the following
2196 issues and workarounds for particular compilers.
2198 .. _`regression test results`: http://www.boost.org/regression/release/user/parameter.html
2204 Some older compilers don't support SFINAE. If your compiler meets
2205 that criterion, then Boost headers will ``#define`` the preprocessor
2206 symbol ``BOOST_NO_SFINAE``, and parameter-enabled functions won't be
2207 removed from the overload set based on their signatures.
2209 ---------------------------
2210 No Support for |result_of|_
2211 ---------------------------
2213 .. |result_of| replace:: ``result_of``
2215 .. _result_of: ../../../utility/utility.htm#result_of
2217 `Lazy default computation`_ relies on the |result_of| class
2218 template to compute the types of default arguments given the type
2219 of the function object that constructs them. On compilers that
2220 don't support |result_of|, ``BOOST_NO_RESULT_OF`` will be
2221 ``#define``\ d, and the compiler will expect the function object to
2222 contain a nested type name, ``result_type``, that indicates its
2223 return type when invoked without arguments. To use an ordinary
2224 function as a default generator on those compilers, you'll need to
2225 wrap it in a class that provides ``result_type`` as a ``typedef``
2226 and invokes the function via its ``operator()``.
2229 Can't Declare |ParameterSpec| via ``typedef``
2230 =============================================
2232 In principle you can declare a |ParameterSpec| as a ``typedef``
2233 for a specialization of ``parameters<…>``, but Microsoft Visual C++
2234 6.x has been seen to choke on that usage. The workaround is to use
2235 inheritance and declare your |ParameterSpec| as a class:
2239 **struct dfs_parameters
2240 :** parameter::parameters<
2241 tag::graph, tag::visitor, tag::root_vertex
2242 , tag::index_map, tag::color_map
2246 Default Arguments Unsupported on Nested Templates
2247 =================================================
2249 As of this writing, Borland compilers don't support the use of
2250 default template arguments on member class templates. As a result,
2251 you have to supply ``BOOST_PARAMETER_MAX_ARITY`` arguments to every
2252 use of ``parameters<…>::match``. Since the actual defaults used
2253 are unspecified, the workaround is to use
2254 |BOOST_PARAMETER_MATCH|_ to declare default arguments for SFINAE.
2256 .. |BOOST_PARAMETER_MATCH| replace:: ``BOOST_PARAMETER_MATCH``
2258 --------------------------------------------------
2259 Compiler Can't See References In Unnamed Namespace
2260 --------------------------------------------------
2262 If you use Microsoft Visual C++ 6.x, you may find that the compiler
2263 has trouble finding your keyword objects. This problem has been
2264 observed, but only on this one compiler, and it disappeared as the
2265 test code evolved, so we suggest you use it only as a last resort
2266 rather than as a preventative measure. The solution is to add
2267 *using-declarations* to force the names to be available in the
2268 enclosing namespace without qualification::
2272 using graphs::graph;
2273 using graphs::visitor;
2274 using graphs::root_vertex;
2275 using graphs::index_map;
2276 using graphs::color_map;
2283 .. _python: python.html
2285 Follow `this link`__ for documentation on how to expose
2286 Boost.Parameter-enabled functions to Python with `Boost.Python`_.
2294 .. _reference: reference.html
2296 Follow `this link`__ to the Boost.Parameter reference
2307 :Argument (or “actual argument”): the value actually passed to a
2308 function or class template
2312 :Parameter (or “formal parameter”): the name used to refer to an
2313 argument within a function or class template. For example, the
2314 value of ``f``'s *parameter* ``x`` is given by the *argument*
2317 int f(int x) { return x + 1 }
2324 The authors would like to thank all the Boosters who participated
2325 in the review of this library and its documentation, most
2326 especially our review manager, Doug Gregor.
2328 --------------------------
2330 .. [#old_interface] As of Boost 1.33.0 the Graph library was still
2331 using an `older named parameter mechanism`__, but there are
2332 plans to change it to use Boost.Parameter (this library) in an
2333 upcoming release, while keeping the old interface available for
2334 backward-compatibility.
2336 __ ../../../graph/doc/bgl_named_params.html
2338 .. [#odr] The **One Definition Rule** says that any given entity in
2339 a C++ program must have the same definition in all translation
2340 units (object files) that make up a program.
2342 .. [#vertex_descriptor] If you're not familiar with the Boost Graph
2343 Library, don't worry about the meaning of any
2344 Graph-library-specific details you encounter. In this case you
2345 could replace all mentions of vertex descriptor types with
2346 ``int`` in the text, and your understanding of the Parameter
2347 library wouldn't suffer.
2349 .. [#ConceptCpp] This is a major motivation behind `ConceptC++`_.
2351 .. _`ConceptC++`: http://www.generic-programming.org/software/ConceptGCC/
2353 .. .. [#bind] The Lambda library is known not to work on `some
2354 .. less-conformant compilers`__. When using one of those you could
2355 .. use `Boost.Bind`_ to generate the function object::
2357 .. boost::bind(std::plus<std::string>(),s1,s2)
2359 .. [#is_keyword_expression] Here we're assuming there's a predicate
2360 metafunction ``is_keyword_expression`` that can be used to
2361 identify models of Boost.Python's KeywordExpression concept.
2363 .. .. __ http://www.boost.org/regression/release/user/lambda.html
2364 .. _Boost.Bind: ../../../bind/index.html
2367 .. [#using] You can always give the illusion that the function
2368 lives in an outer namespace by applying a *using-declaration*::
2370 namespace foo_overloads
2372 // foo declarations here
2376 using foo_overloads::foo;
2378 This technique for avoiding unintentional argument-dependent
2379 lookup is due to Herb Sutter.
2382 .. [#sfinae] This capability depends on your compiler's support for SFINAE.
2383 **SFINAE**: **S**\ ubstitution **F**\ ailure **I**\ s
2384 **N**\ ot **A**\ n **E** rror. If type substitution during the
2385 instantiation of a function template results in an invalid type,
2386 no compilation error is emitted; instead the overload is removed
2387 from the overload set. By producing an invalid type in the
2388 function signature depending on the result of some condition,
2389 we can decide whether or not an overload is considered during overload
2390 resolution. The technique is formalized in
2391 the |enable_if|_ utility. Most recent compilers support SFINAE;
2392 on compilers that don't support it, the Boost config library
2393 will ``#define`` the symbol ``BOOST_NO_SFINAE``.
2395 http://www.semantics.org/once_weakly/w02_SFINAE.pdf for more
2396 information on SFINAE.
2398 .. |enable_if| replace:: ``enable_if``
2399 .. _enable_if: ../../../utility/enable_if.html