1++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2The Boost Parameter Library 3++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 5|(logo)|__ 6 7.. |(logo)| image:: ../../../../boost.png 8 :alt: Boost 9 10__ ../../../../index.htm 11 12------------------------------------- 13 14:Abstract: Use this library to write functions and class templates that can 15 accept arguments by name: 16 17.. parsed-literal:: 18 19 new_window( 20 "alert" 21 , **_width=10** 22 , **_titlebar=false** 23 ); 24 25 smart_ptr< 26 Foo 27 , **deleter<Deallocate<Foo> >** 28 , **copy_policy<DeepCopy>** 29 > p(new Foo); 30 31Since named arguments can be passed in any order, they are especially useful 32when a function or template has more than one parameter with a useful default 33value. The library also supports *deduced* parameters: that is to say, 34parameters whose identity can be deduced from their types. 35 36.. @jam_prefix.append(''' 37 project test 38 : requirements <include>. <implicit-dependency>/boost//headers ; 39 ''') 40 41.. @example.prepend(''' 42 #include <boost/parameter.hpp> 43 44 namespace test { 45 46 BOOST_PARAMETER_NAME(title) 47 BOOST_PARAMETER_NAME(width) 48 BOOST_PARAMETER_NAME(titlebar) 49 50 BOOST_PARAMETER_FUNCTION( 51 (int), new_window, tag, (required (title,*)(width,*)(titlebar,*)) 52 ) 53 { 54 return 0; 55 } 56 57 BOOST_PARAMETER_TEMPLATE_KEYWORD(deleter) 58 BOOST_PARAMETER_TEMPLATE_KEYWORD(copy_policy) 59 60 template <typename T> 61 struct Deallocate 62 { 63 }; 64 65 struct DeepCopy 66 { 67 }; 68 69 namespace parameter = boost::parameter; 70 71 struct Foo 72 { 73 }; 74 75 template <typename T, typename A0, typename A1> 76 struct smart_ptr 77 { 78 smart_ptr(Foo*); 79 }; 80 } 81 using namespace test; 82 int x = 83 '''); 84 85.. @test('compile') 86 87 88------------------------------------- 89 90:Authors: David Abrahams, Daniel Wallin 91:Contact: dave@boost-consulting.com, daniel@boostpro.com 92:organization: `BoostPro Computing`_ 93:date: $Date: 2005/07/17 19:53:01 $ 94 95:copyright: Copyright David Abrahams, Daniel Wallin 96 2005-2009. Distributed under the Boost Software License, 97 Version 1.0. (See accompanying file LICENSE_1_0.txt 98 or copy at http://www.boost.org/LICENSE_1_0.txt) 99 100.. _`BoostPro Computing`: http://www.boostpro.com 101 102.. _concepts: http://www.boost.org/more/generic_programming.html#concept 103 104------------------------------------- 105 106[Note: this tutorial does not cover all details of the library. Please see 107also the `reference documentation`__\ ] 108 109__ reference.html 110 111.. contents:: **Table of Contents** 112 :depth: 2 113 114.. role:: concept 115 :class: concept 116 117.. role:: vellipsis 118 :class: vellipsis 119 120.. section-numbering:: 121 122------------------------------------- 123 124========== 125Motivation 126========== 127 128In C++, arguments_ are normally given meaning by their positions with respect 129to a parameter_ list: the first argument passed maps onto the first parameter 130in a function's definition, and so on. That protocol is fine when there is at 131most one parameter with a default value, but when there are even a few useful 132defaults, the positional interface becomes burdensome: 133 134* .. compound:: 135 136 Since an argument's meaning is given by its position, we have to choose an 137 (often arbitrary) order for parameters with default values, making some 138 combinations of defaults unusable: 139 140 .. parsed-literal:: 141 142 window* new_window( 143 char const* name 144 , **int border_width = default_border_width** 145 , bool movable = true 146 , bool initially_visible = true 147 ); 148 149 bool const movability = false; 150 window* w = new_window("alert box", movability); 151 152 In the example above we wanted to make an unmoveable window with a default 153 ``border_width``, but instead we got a moveable window with a 154 ``border_width`` of zero. To get the desired effect, we'd need to write: 155 156 .. parsed-literal:: 157 158 window* w = new_window( 159 "alert box", **default_border_width**, movability 160 ); 161 162* .. compound:: 163 164 It can become difficult for readers to understand the meaning of arguments 165 at the call site:: 166 167 window* w = new_window("alert", 1, true, false); 168 169 Is this window moveable and initially invisible, or unmoveable and 170 initially visible? The reader needs to remember the order of arguments to 171 be sure. 172 173* The author of the call may not remember the order of the arguments either, 174 leading to hard-to-find bugs. 175 176.. @ignore(3) 177 178------------------------- 179Named Function Parameters 180------------------------- 181 182.. compound:: 183 184 This library addresses the problems outlined above by associating each 185 parameter name with a keyword object. Now users can identify arguments by 186 name, rather than by position: 187 188 .. parsed-literal:: 189 190 window* w = new_window( 191 "alert box" 192 , **movable_=**\ false 193 ); // OK! 194 195.. @ignore() 196 197--------------------------- 198Deduced Function Parameters 199--------------------------- 200 201.. compound:: 202 203 A **deduced parameter** can be passed in any position *without* supplying 204 an explicit parameter name. It's not uncommon for a function to have 205 parameters that can be uniquely identified based on the types of arguments 206 passed. The ``name`` parameter to ``new_window`` is one such 207 example. None of the other arguments, if valid, can reasonably be 208 converted to a ``char const*``. With a deduced parameter interface, we 209 could pass the window name in *any* argument position without causing 210 ambiguity: 211 212 .. parsed-literal:: 213 214 window* w = new_window( 215 movable_=false 216 , **"alert box"** 217 ); // OK! 218 window* w = new_window( 219 **"alert box"** 220 , movable_=false 221 ); // OK! 222 223 Appropriately used, a deduced parameter interface can free the user of the 224 burden of even remembering the formal parameter names. 225 226.. @ignore() 227 228-------------------------------- 229Class Template Parameter Support 230-------------------------------- 231 232.. compound:: 233 234 The reasoning we've given for named and deduced parameter interfaces 235 applies equally well to class templates as it does to functions. Using 236 the Parameter library, we can create interfaces that allow template 237 arguments (in this case ``shared`` and ``Client``) to be explicitly named, 238 like this: 239 240 .. parsed-literal:: 241 242 smart_ptr< 243 **ownership<shared>** 244 , **value_type<Client>** 245 > p; 246 247 The syntax for passing named template arguments is not quite as natural as 248 it is for function arguments (ideally, we'd be able to write 249 ``smart_ptr<ownership = shared, …>``). This small syntactic deficiency 250 makes deduced parameters an especially big win when used with class 251 templates: 252 253 .. parsed-literal:: 254 255 // *p and q could be equivalent, given a deduced* 256 // *parameter interface.* 257 smart_ptr<**shared**, **Client**> p; 258 smart_ptr<**Client**, **shared**> q; 259 260.. @ignore(2) 261 262======== 263Tutorial 264======== 265 266This tutorial shows all the basics—how to build both named- and 267deduced-parameter interfaces to function templates and class 268templates—and several more advanced idioms as well. 269 270--------------------------- 271Parameter-Enabled Functions 272--------------------------- 273 274In this section we'll show how the Parameter library can be used to 275build an expressive interface to the `Boost Graph library`__\ 's 276|dfs|_ algorithm. [#old_interface]_ 277 278.. Revisit this 279 280 After laying some groundwork and describing the algorithm's abstract 281 interface, we'll show you how to build a basic implementation with keyword 282 support. Then we'll add support for default arguments and we'll gradually 283 refine the implementation with syntax improvements. Finally we'll show 284 how to streamline the implementation of named parameter interfaces, 285 improve their participation in overload resolution, and optimize their 286 runtime efficiency. 287 288__ ../../../graph/doc/index.html 289 290.. _dfs: ../../../graph/doc/depth_first_search.html 291 292.. |dfs| replace:: ``depth_first_search`` 293 294 295Headers And Namespaces 296====================== 297 298Most components of the Parameter library are declared in a header named for 299the component. For example, :: 300 301 #include <boost/parameter/keyword.hpp> 302 303will ensure ``boost::parameter::keyword`` is known to the compiler. There 304is also a combined header, ``boost/parameter.hpp``, that includes most of 305the library's components. For the the rest of this tutorial, unless we 306say otherwise, you can use the rule above to figure out which header to 307``#include`` to access any given component of the library. 308 309.. @example.append(''' 310 using boost::parameter::keyword; 311 ''') 312 313.. @test('compile') 314 315Also, the examples below will also be written as if the namespace alias :: 316 317 namespace parameter = boost::parameter; 318 319.. @ignore() 320 321has been declared: we'll write ``parameter::xxx`` instead of 322``boost::parameter::xxx``. 323 324The Abstract Interface to |dfs| 325=============================== 326 327The Graph library's |dfs| algorithm is a generic function accepting 328from one to four arguments by reference. If all arguments were 329required, its signature might be as follows:: 330 331 template < 332 typename Graph 333 , typename DFSVisitor 334 , typename Index 335 , typename ColorMap 336 > 337 void 338 depth_first_search( 339 Graph const& graph 340 , DFSVisitor visitor 341 , typename graph_traits<g>::vertex_descriptor root_vertex 342 , IndexMap index_map 343 , ColorMap& color 344 ); 345 346.. @ignore() 347 348However, most of the parameters have a useful default value, 349as shown in the table below. 350 351.. _`parameter table`: 352.. _`default expressions`: 353 354.. table:: ``depth_first_search`` Parameters 355 356 +-----------------+------+-------------------------+------------------------------------+ 357 | Parameter | Data | Type | Default Value | 358 | Name | Flow | | (if any) | 359 +=================+======+=========================+====================================+ 360 | ``graph`` | in | Model of | none - this argument is required. | 361 | | | |IncidenceGraph|_ and | | 362 | | | |VertexListGraph|_ | | 363 +-----------------+------+-------------------------+------------------------------------+ 364 | ``visitor`` | in | Model of |DFSVisitor|_ | ``boost::dfs_visitor<>()`` | 365 +-----------------+------+-------------------------+------------------------------------+ 366 | ``root_vertex`` | in | ``graph``'s vertex | ``*vertices(graph).first`` | 367 | | | descriptor type. | | 368 +-----------------+------+-------------------------+------------------------------------+ 369 | ``index_map`` | in | Model of | ``get(boost::vertex_index,graph)`` | 370 | | | |ReadablePropertyMap|_ | | 371 | | | with key type := | | 372 | | | ``graph``'s vertex | | 373 | | | descriptor and value | | 374 | | | type an integer type. | | 375 +-----------------+------+-------------------------+------------------------------------+ 376 | ``color_map`` | in / | Model of | a ``boost::iterator_property_map`` | 377 | | out | |ReadWritePropertyMap|_ | created from a ``std::vector`` of | 378 | | | with key type := | ``default_color_type`` of size | 379 | | | ``graph``'s vertex | ``num_vertices(graph)`` and using | 380 | | | descriptor type. | ``index_map`` for the index map. | 381 +-----------------+------+-------------------------+------------------------------------+ 382 383.. |IncidenceGraph| replace:: :concept:`Incidence Graph` 384.. |VertexListGraph| replace:: :concept:`Vertex List Graph` 385.. |DFSVisitor| replace:: :concept:`DFS Visitor` 386.. |ReadablePropertyMap| replace:: :concept:`Readable Property Map` 387.. |ReadWritePropertyMap| replace:: :concept:`Read/Write Property Map` 388 389.. _`IncidenceGraph`: ../../../graph/doc/IncidenceGraph.html 390.. _`VertexListGraph`: ../../../graph/doc/VertexListGraph.html 391.. _`DFSVisitor`: ../../../graph/doc/DFSVisitor.html 392.. _`ReadWritePropertyMap`: ../../../property_map/doc/ReadWritePropertyMap.html 393.. _`ReadablePropertyMap`: ../../../property_map/doc/ReadablePropertyMap.html 394 395Don't be intimidated by the information in the second and third columns 396above. For the purposes of this exercise, you don't need to understand 397them in detail. 398 399Defining the Keywords 400===================== 401 402The point of this exercise is to make it possible to call 403``depth_first_search`` with named arguments, leaving out any 404arguments for which the default is appropriate: 405 406.. parsed-literal:: 407 408 graphs::depth_first_search(g, **color_map_=my_color_map**); 409 410.. @ignore() 411 412To make that syntax legal, there needs to be an object called 413“\ ``color_map_``\ ” whose assignment operator can accept a 414``my_color_map`` argument. In this step we'll create one such 415**keyword object** for each parameter. Each keyword object will be 416identified by a unique **keyword tag type**. 417 418.. Revisit this 419 420 We're going to define our interface in namespace ``graphs``. Since users 421 need access to the keyword objects, but not the tag types, we'll define 422 the keyword objects so they're accessible through ``graphs``, and we'll 423 hide the tag types away in a nested namespace, ``graphs::tag``. The 424 library provides a convenient macro for that purpose. 425 426We're going to define our interface in namespace ``graphs``. The 427library provides a convenient macro for defining keyword objects:: 428 429 #include <boost/parameter/name.hpp> 430 431 namespace graphs { 432 433 BOOST_PARAMETER_NAME(graph) // Note: no semicolon 434 BOOST_PARAMETER_NAME(visitor) 435 BOOST_PARAMETER_NAME(root_vertex) 436 BOOST_PARAMETER_NAME(index_map) 437 BOOST_PARAMETER_NAME(color_map) 438 } 439 440.. @test('compile') 441 442The declaration of the ``graph`` keyword you see here is equivalent to:: 443 444 namespace graphs { 445 namespace tag { 446 447 // keyword tag type 448 struct graph 449 { 450 typedef boost::parameter::forward_reference qualifier; 451 }; 452 } 453 454 namespace // unnamed 455 { 456 // A reference to the keyword object 457 boost::parameter::keyword<tag::graph> const& _graph 458 = boost::parameter::keyword<tag::graph>::instance; 459 } 460 } 461 462.. @example.prepend('#include <boost/parameter/keyword.hpp>') 463.. @test('compile') 464 465It defines a *keyword tag type* named ``tag::graph`` and a *keyword object* 466reference named ``_graph``. 467 468This “fancy dance” involving an unnamed namespace and references is all done 469to avoid violating the One Definition Rule (ODR) [#odr]_ when the named 470parameter interface is used by function templates that are instantiated in 471multiple translation units (MSVC6.x users see `this note`__). 472 473__ `Compiler Can't See References In Unnamed Namespace`_ 474 475Writing the Function 476==================== 477 478Now that we have our keywords defined, the function template definition 479follows a simple pattern using the ``BOOST_PARAMETER_FUNCTION`` macro:: 480 481 #include <boost/parameter/preprocessor.hpp> 482 483 namespace graphs { 484 485 BOOST_PARAMETER_FUNCTION( 486 (void), // 1. parenthesized return type 487 depth_first_search, // 2. name of the function template 488 tag, // 3. namespace of tag types 489 (required (graph, *) ) // 4. one required parameter, and 490 (optional // four optional parameters, 491 // with defaults 492 (visitor, *, boost::dfs_visitor<>()) 493 (root_vertex, *, *vertices(graph).first) 494 (index_map, *, get(boost::vertex_index,graph)) 495 (color_map, *, 496 default_color_map(num_vertices(graph), index_map) 497 ) 498 ) 499 ) 500 { 501 // ... body of function goes here... 502 // use graph, visitor, index_map, and color_map 503 } 504 } 505 506.. @example.prepend(''' 507 #include <boost/parameter/name.hpp> 508 509 BOOST_PARAMETER_NAME(graph) 510 BOOST_PARAMETER_NAME(visitor) 511 BOOST_PARAMETER_NAME(in(root_vertex)) 512 BOOST_PARAMETER_NAME(in(index_map)) 513 BOOST_PARAMETER_NAME(in_out(color_map)) 514 515 namespace boost { 516 517 template <typename T = int> 518 struct dfs_visitor 519 { 520 }; 521 522 int vertex_index = 0; 523 } 524 ''') 525 526.. @test('compile') 527 528The arguments to ``BOOST_PARAMETER_FUNCTION`` are: 529 5301. The return type of the resulting function template. Parentheses around 531 the return type prevent any commas it might contain from confusing the 532 preprocessor, and are always required. 533 5342. The name of the resulting function template. 535 5363. The name of a namespace where we can find tag types whose names match the 537 function's parameter names. 538 5394. The function signature. 540 541Function Signatures 542=================== 543 544Function signatures are described as one or two adjacent parenthesized terms 545(a Boost.Preprocessor_ sequence_) describing the function's parameters in the 546order in which they'd be expected if passed positionally. Any required 547parameters must come first, but the ``(required … )`` clause can be omitted 548when all the parameters are optional. 549 550.. _Boost.Preprocessor: ../../../preprocessor/doc/index.html 551.. _sequence: http://boost-consulting.com/mplbook/preprocessor.html#sequences 552 553Required Parameters 554------------------- 555 556.. compound:: 557 558 Required parameters are given first—nested in a ``(required … )`` 559 clause—as a series of two-element tuples describing each parameter name 560 and any requirements on the argument type. In this case there is only a 561 single required parameter, so there's just a single tuple: 562 563 .. parsed-literal:: 564 565 (required **(graph, \*)** ) 566 567 Since ``depth_first_search`` doesn't require any particular type for its 568 ``graph`` parameter, we use an asterix to indicate that any type is 569 allowed. Required parameters must always precede any optional parameters 570 in a signature, but if there are *no* required parameters, the 571 ``(required … )`` clause can be omitted entirely. 572 573.. @example.prepend(''' 574 #include <boost/parameter.hpp> 575 576 BOOST_PARAMETER_NAME(graph) 577 578 BOOST_PARAMETER_FUNCTION((void), f, tag, 579 ''') 580 581.. @example.append(') {}') 582.. @test('compile') 583 584Optional Parameters 585------------------- 586 587.. compound:: 588 589 Optional parameters—nested in an ``(optional … )`` clause—are given as a 590 series of adjacent *three*\ -element tuples describing the parameter name, 591 any requirements on the argument type, *and* and an expression 592 representing the parameter's default value: 593 594 .. parsed-literal:: 595 596 (optional 597 **(visitor, \*, boost::dfs_visitor<>()) 598 (root_vertex, \*, \*vertices(graph).first) 599 (index_map, \*, get(boost::vertex_index,graph)) 600 (color_map, \*, 601 default_color_map(num_vertices(graph), index_map) 602 )** 603 ) 604 605.. @example.prepend(''' 606 #include <boost/parameter.hpp> 607 608 namespace boost { 609 610 int vertex_index = 0; 611 612 template <typename T = int> 613 struct dfs_visitor 614 { 615 }; 616 } 617 618 BOOST_PARAMETER_NAME(graph) 619 BOOST_PARAMETER_NAME(visitor) 620 BOOST_PARAMETER_NAME(in(root_vertex)) 621 BOOST_PARAMETER_NAME(in(index_map)) 622 BOOST_PARAMETER_NAME(in_out(color_map)) 623 624 BOOST_PARAMETER_FUNCTION((void), f, tag, 625 (required (graph, \*)) 626 ''') 627 628.. @example.append(') {}') 629.. @test('compile') 630 631Handling “In”, “Out”, “Consume / Move-From”, and “Forward” Parameters 632--------------------------------------------------------------------- 633 634.. compound:: 635 636 By default, Boost.Parameter treats all parameters as if they were 637 *forward* `parameters`_, which functions would take in by rvalue reference 638 and only ``std::forward`` or ``boost::forward`` to other functions. Such 639 parameters can be ``const`` lvalues, mutable lvalues, ``const`` rvalues, 640 or mutable rvalues. Therefore, the default configuration grants the most 641 flexibility to user code. However: 642 643 * Users can configure one or more parameters to be *in* `parameters`_, 644 which can fall into the same categories as *forward* `parameters`_ but 645 are now passed by ``const`` lvalue reference and so must only be read 646 from. Continuing from the previous example, to indicate that 647 ``root_vertex`` and ``index_map`` are read-only, we wrap their names 648 in ``in(…)``. 649 650 * Users can configure one or more parameters to be either *out* 651 `parameters`_, which functions would strictly write to, or *in-out* 652 `parameters`_, which functions would both read from and write 653 to. Such parameters can only be mutable lvalues. In the example, to 654 indicate that ``color_map`` is read-write, we wrap its name in 655 ``in_out(…)``. Note that Boost.Parameter sees no functional 656 difference between ``out(…)`` and ``in_out(…)``, so you may choose 657 whichever makes your interfaces more self-documenting. 658 659 * Users can configure one or more parameters to be *consume* or 660 *move-from* `parameters`_, which functions would take in by mutable 661 rvalue reference and ``std::move`` or ``boost::move`` as the last 662 access step. Such parameters can only be mutable 663 rvalues. Boost.Parameter supports wrapping the corresponding names in 664 ``consume(…)`` or ``move_from(…)``. 665 666 .. parsed-literal:: 667 668 BOOST_PARAMETER_NAME(graph) 669 BOOST_PARAMETER_NAME(visitor) 670 BOOST_PARAMETER_NAME(**in(root_vertex)**) 671 BOOST_PARAMETER_NAME(**in(index_map)**) 672 BOOST_PARAMETER_NAME(**in_out(color_map)**) 673 674 In order to see what happens when parameters are bound to arguments that 675 violate their category constraints, attempt to compile the |compose_cpp|_ 676 test program with either the ``LIBS_PARAMETER_TEST_COMPILE_FAILURE_0`` 677 macro or the ``LIBS_PARAMETER_TEST_COMPILE_FAILURE_1`` macro 678 ``#defined``. You should encounter a compiler error caused by a specific 679 constraint violation. 680 681.. @example.prepend(''' 682 #include <boost/parameter.hpp> 683 684 namespace boost { 685 686 int vertex_index = 0; 687 688 template <typename T = int> 689 struct dfs_visitor 690 { 691 }; 692 } 693 ''') 694 695.. @example.append(''' 696 BOOST_PARAMETER_FUNCTION((void), f, tag, 697 (required (graph, \*)) 698 (optional 699 (visitor, \*, boost::dfs_visitor<>()) 700 (root_vertex, \*, \*vertices(graph).first) 701 (index_map, \*, get(boost::vertex_index, graph)) 702 (color_map, \*, 703 default_color_map(num_vertices(graph), index_map) 704 ) 705 ) 706 ) 707 { 708 } 709 ''') 710 711.. @test('compile') 712 713.. _`parameters`: http://www.modernescpp.com/index.php/c-core-guidelines-how-to-pass-function-parameters 714.. |compose_cpp| replace:: compose.cpp 715.. _compose_cpp: ../../test/compose.cpp 716 717Positional Arguments 718-------------------- 719 720When arguments are passed positionally (without the use of keywords), they 721will be mapped onto parameters in the order the parameters are given in the 722signature, so for example in this call :: 723 724 graphs::depth_first_search(x, y); 725 726.. @ignore() 727 728``x`` will always be interpreted as a graph and ``y`` will always be 729interpreted as a visitor. 730 731Default Expression Evaluation 732----------------------------- 733 734.. compound:: 735 736 Note that in our example, the value of the graph parameter is used in the 737 default expressions for ``root_vertex``, ``index_map``, and ``color_map``. 738 739 .. parsed-literal:: 740 741 (required (**graph**, \*) ) 742 (optional 743 (visitor, \*, boost::dfs_visitor<>()) 744 (root_vertex, \*, \*vertices(**graph**).first) 745 (index_map, \*, get(boost::vertex_index, **graph**)) 746 (color_map, \*, 747 default_color_map(num_vertices(**graph**), index_map) 748 ) 749 ) 750 751.. @ignore() 752 753 A default expression is evaluated in the context of all preceding 754 parameters, so you can use any of their values by name. 755 756.. compound:: 757 758 A default expression is never evaluated—or even instantiated—if an actual 759 argument is passed for that parameter. We can actually demonstrate that 760 with our code so far by replacing the body of ``depth_first_search`` with 761 something that prints the arguments: 762 763 .. parsed-literal:: 764 765 #include <boost/graph/depth_first_search.hpp> // for dfs_visitor 766 767 BOOST_PARAMETER_FUNCTION( 768 (bool), depth_first_search, tag 769 *…signature goes here…* 770 ) 771 { 772 std::cout << "graph=" << graph; 773 std::cout << std::endl; 774 std::cout << "visitor=" << visitor; 775 std::cout << std::endl; 776 std::cout << "root_vertex=" << root_vertex; 777 std::cout << std::endl; 778 std::cout << "index_map=" << index_map; 779 std::cout << std::endl; 780 std::cout << "color_map=" << color_map; 781 std::cout << std::endl; 782 return true; 783 } 784 785 #include <boost/core/lightweight_test.hpp> 786 787 int main() 788 { 789 char const\* g = "1"; 790 depth_first_search(1, 2, 3, 4, 5); 791 depth_first_search( 792 g, '2', _color_map = '5', 793 _index_map = "4", _root_vertex = "3" 794 ); 795 return boost::report_errors(); 796 } 797 798 Despite the fact that default expressions such as 799 ``vertices(graph).first`` are ill-formed for the given ``graph`` 800 arguments, both calls will compile, and each one will print exactly the 801 same thing. 802 803.. @example.prepend(''' 804 #include <boost/parameter.hpp> 805 #include <iostream> 806 807 BOOST_PARAMETER_NAME(graph) 808 BOOST_PARAMETER_NAME(visitor) 809 BOOST_PARAMETER_NAME(root_vertex) 810 BOOST_PARAMETER_NAME(index_map) 811 BOOST_PARAMETER_NAME(color_map) 812 ''') 813 814.. @example.replace_emphasis(''' 815 , (required 816 (graph, \*) 817 (visitor, \*) 818 (root_vertex, \*) 819 (index_map, \*) 820 (color_map, \*) 821 ) 822 ''') 823.. @test('run') 824 825Signature Matching and Overloading 826---------------------------------- 827 828In fact, the function signature is so general that any call to 829``depth_first_search`` with fewer than five arguments will match our function, 830provided we pass *something* for the required ``graph`` parameter. That might 831not seem to be a problem at first; after all, if the arguments don't match the 832requirements imposed by the implementation of ``depth_first_search``, a 833compilation error will occur later, when its body is instantiated. 834 835There are at least three problems with very general function signatures. 836 8371. By the time our ``depth_first_search`` is instantiated, it has been 838 selected as the best matching overload. Some other ``depth_first_search`` 839 overload might've worked had it been chosen instead. By the time we see a 840 compilation error, there's no chance to change that decision. 841 8422. Even if there are no overloads, error messages generated at instantiation 843 time usually expose users to confusing implementation details. For 844 example, users might see references to names generated by 845 ``BOOST_PARAMETER_FUNCTION`` such as 846 ``graphs::detail::depth_first_search_with_named_params`` (or worse—think 847 of the kinds of errors you get from your STL implementation when you make 848 a mistake). [#ConceptsTS]_ 849 8503. The problems with exposing such permissive function template signatures 851 have been the subject of much discussion, especially in the presence of 852 `unqualified calls`__. If all we want is to avoid unintentional 853 argument-dependent lookup (ADL), we can isolate ``depth_first_search`` in 854 a namespace containing no types [#using]_, but suppose we *want* it to 855 found via ADL? 856 857__ http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#225 858 859It's usually a good idea to prevent functions from being considered for 860overload resolution when the passed argument types aren't appropriate. The 861library already does this when the required ``graph`` parameter is not 862supplied, but we're not likely to see a depth first search that doesn't take a 863graph to operate on. Suppose, instead, that we found a different depth first 864search algorithm that could work on graphs that don't model 865|IncidenceGraph|_? If we just added a simple overload, it would be 866ambiguous:: 867 868 // new overload 869 BOOST_PARAMETER_FUNCTION((void), depth_first_search, (tag), 870 (required (graph,*))( … ) 871 ) 872 { 873 // new algorithm implementation 874 } 875 876 … 877 878 // ambiguous! 879 depth_first_search(boost::adjacency_list<>(), 2, "hello"); 880 881.. @ignore() 882 883Predicate Requirements 884...................... 885 886We really don't want the compiler to consider the original version of 887``depth_first_search`` because the ``root_vertex`` argument, ``"hello"``, 888doesn't meet the requirement__ that it match the ``graph`` parameter's vertex 889descriptor type. Instead, this call should just invoke our new overload. To 890take the original ``depth_first_search`` overload out of contention, we first 891encode this requirement as follows: 892 893__ `parameter table`_ 894 895.. parsed-literal:: 896 897 struct vertex_descriptor_predicate 898 { 899 template <typename T, typename Args> 900 struct apply 901 : boost::mpl::if_< 902 boost::is_convertible< 903 T 904 , typename boost::graph_traits< 905 typename boost::parameter::value_type< 906 Args 907 , graphs::graph 908 >::type 909 >::vertex_descriptor 910 > 911 , boost::mpl::true\_ 912 , boost::mpl::false\_ 913 > 914 { 915 }; 916 }; 917 918This encoding is an `MPL Binary Metafunction Class`__, a type with a nested 919``apply`` metafunction that takes in two template arguments. For the first 920template argument, Boost.Parameter will pass in the type on which we will 921impose the requirement. For the second template argument, Boost.Parameter 922will pass in the entire argument pack, making it possible to extract the 923type of each of the other ``depth_first_search`` parameters via the 924``value_type`` metafunction and the corresponding keyword tag type. The 925result ``type`` of the ``apply`` metafunction will be equivalent to 926``boost::mpl::true_`` if ``T`` fulfills our requirement as imposed by the 927``boost::is_convertible`` statement; otherwise, the result will be 928equivalent to ``boost::mpl::false_``. 929 930__ ../../../mpl/doc/refmanual/metafunction-class.html 931 932At this point, we can append the name of our metafunction class, in 933parentheses, to the appropriate ``*`` element of the function signature. 934 935.. parsed-literal:: 936 937 (root_vertex 938 , \*(**vertex_descriptor_predicate**) 939 , \*vertices(graph).first 940 ) 941 942.. @ignore() 943 944Now the original ``depth_first_search`` will only be called when the 945``root_vertex`` argument can be converted to the graph's vertex descriptor 946type, and our example that *was* ambiguous will smoothly call the new 947overload. 948 949We can encode the requirements on other arguments using the same concept; only 950the implementation of the nested ``apply`` metafunction needs to be tweaked 951for each argument. There's no space to give a complete description of graph 952library details here, but suffice it to show that the next few metafunction 953classes provide the necessary checks. 954 955.. parsed-literal:: 956 957 struct graph_predicate 958 { 959 template <typename T, typename Args> 960 struct apply 961 : boost::mpl::eval_if< 962 boost::is_convertible< 963 typename boost::graph_traits<T>::traversal_category 964 , boost::incidence_graph_tag 965 > 966 , boost::mpl::if_< 967 boost::is_convertible< 968 typename boost::graph_traits<T>::traversal_category 969 , boost::vertex_list_graph_tag 970 > 971 , boost::mpl::true\_ 972 , boost::mpl::false\_ 973 > 974 > 975 { 976 }; 977 }; 978 979 struct index_map_predicate 980 { 981 template <typename T, typename Args> 982 struct apply 983 : boost::mpl::eval_if< 984 boost::is_integral< 985 typename boost::property_traits<T>::value_type 986 > 987 , boost::mpl::if_< 988 boost::is_same< 989 typename boost::property_traits<T>::key_type 990 , typename boost::graph_traits< 991 typename boost::parameter::value_type< 992 Args 993 , graphs::graph 994 >::type 995 >::vertex_descriptor 996 > 997 , boost::mpl::true\_ 998 , boost::mpl::false\_ 999 > 1000 > 1001 { 1002 }; 1003 }; 1004 1005 struct color_map_predicate 1006 { 1007 template <typename T, typename Args> 1008 struct apply 1009 : boost::mpl::if_< 1010 boost::is_same< 1011 typename boost::property_traits<T>::key_type 1012 , typename boost::graph_traits< 1013 typename boost::parameter::value_type< 1014 Args 1015 , graphs::graph 1016 >::type 1017 >::vertex_descriptor 1018 > 1019 , boost::mpl::true\_ 1020 , boost::mpl::false\_ 1021 > 1022 { 1023 }; 1024 }; 1025 1026Likewise, computing the default value for the ``color_map`` parameter is no 1027trivial matter, so it's best to factor the computation out to a separate 1028function template. 1029 1030.. parsed-literal:: 1031 1032 template <typename Size, typename IndexMap> 1033 boost::iterator_property_map< 1034 std::vector<boost::default_color_type>::iterator 1035 , IndexMap 1036 , boost::default_color_type 1037 , boost::default_color_type& 1038 >& 1039 default_color_map(Size num_vertices, IndexMap const& index_map) 1040 { 1041 static std::vector<boost::default_color_type> colors(num_vertices); 1042 static boost::iterator_property_map< 1043 std::vector<boost::default_color_type>::iterator 1044 , IndexMap 1045 , boost::default_color_type 1046 , boost::default_color_type& 1047 > m(colors.begin(), index_map); 1048 return m; 1049 } 1050 1051The signature encloses each predicate metafunction in parentheses *preceded 1052by an asterix*, as follows: 1053 1054.. parsed-literal:: 1055 1056 BOOST_PARAMETER_FUNCTION((void), depth_first_search, graphs, 1057 (required 1058 (graph, \*(**graph_predicate**)) 1059 ) 1060 (optional 1061 (visitor 1062 , \* // not easily checkable 1063 , boost::dfs_visitor<>() 1064 ) 1065 (root_vertex 1066 , (**vertex_descriptor_predicate**) 1067 , \*vertices(graph).first 1068 ) 1069 (index_map 1070 , \*(**index_map_predicate**) 1071 , get(boost::vertex_index, graph) 1072 ) 1073 (color_map 1074 , \*(**color_map_predicate**) 1075 , default_color_map(num_vertices(graph), index_map) 1076 ) 1077 ) 1078 ) 1079 1080.. @example.prepend(''' 1081 #include <boost/parameter.hpp> 1082 #include <boost/graph/adjacency_list.hpp> 1083 #include <boost/graph/depth_first_search.hpp> 1084 #include <boost/graph/graph_traits.hpp> 1085 #include <boost/property_map/property_map.hpp> 1086 #include <boost/mpl/and.hpp> 1087 #include <boost/type_traits/is_convertible.hpp> 1088 #include <boost/type_traits/is_integral.hpp> 1089 #include <boost/type_traits/is_same.hpp> 1090 #include <vector> 1091 #include <utility> 1092 1093 BOOST_PARAMETER_NAME((_graph, graphs) graph) 1094 BOOST_PARAMETER_NAME((_visitor, graphs) visitor) 1095 BOOST_PARAMETER_NAME((_root_vertex, graphs) in(root_vertex)) 1096 BOOST_PARAMETER_NAME((_index_map, graphs) in(index_map)) 1097 BOOST_PARAMETER_NAME((_color_map, graphs) in_out(color_map)) 1098 ''') 1099 1100.. @example.append(''' 1101 { 1102 } 1103 1104 #include <boost/core/lightweight_test.hpp> 1105 #include <boost/graph/adjacency_list.hpp> 1106 #include <utility> 1107 1108 int main() 1109 { 1110 typedef boost::adjacency_list< 1111 boost::vecS, boost::vecS, boost::directedS 1112 > G; 1113 enum {u, v, w, x, y, z, N}; 1114 typedef std::pair<int, int> E; 1115 E edges[] = { 1116 E(u, v), E(u, x), E(x, v), E(y, x), 1117 E(v, y), E(w, y), E(w,z), E(z, z) 1118 }; 1119 G g(edges, edges + sizeof(edges) / sizeof(E), N); 1120 1121 depth_first_search(g); 1122 depth_first_search(g, _root_vertex = static_cast<int>(x)); 1123 return boost::report_errors(); 1124 } 1125 ''') 1126 1127.. @test('run') 1128 1129It usually isn't necessary to so completely encode the type requirements on 1130arguments to generic functions. However, doing so is worth the effort: your 1131code will be more self-documenting and will often provide a better user 1132experience. You'll also have an easier transition to the C++20 standard with 1133`language support for constraints and concepts`__. 1134 1135__ `ConceptsTS`_ 1136 1137More on Type Requirements 1138......................... 1139 1140Encoding type requirements onto a function's parameters is essential for 1141enabling the function to have deduced parameter interface. Let's revisit the 1142``new_window`` example for a moment: 1143 1144.. parsed-literal:: 1145 1146 window\* w = new_window( 1147 movable_=false 1148 , "alert box" 1149 ); 1150 window\* w = new_window( 1151 "alert box" 1152 , movable_=false 1153 ); 1154 1155.. @ignore() 1156 1157The goal this time is to be able to invoke the ``new_window`` function without 1158specifying the keywords. For each parameter that has a required type, we can 1159enclose that type in parentheses, then *replace* the ``*`` element of the 1160parameter signature: 1161 1162.. parsed-literal:: 1163 1164 BOOST_PARAMETER_NAME((name\_, keywords) name) 1165 BOOST_PARAMETER_NAME((movable\_, keywords) movable) 1166 1167 BOOST_PARAMETER_FUNCTION((window\*), new_window, keywords, 1168 (deduced 1169 (required 1170 (name, *(char const\*)*) 1171 (movable, *(bool)*) 1172 ) 1173 ) 1174 ) 1175 { 1176 // ... 1177 } 1178 1179.. @ignore() 1180 1181The following statements will now work and are equivalent to each other as 1182well as the previous statements: 1183 1184.. parsed-literal:: 1185 1186 window\* w = new_window(false, "alert box"); 1187 window\* w = new_window("alert box", false); 1188 1189.. @ignore() 1190 1191Deduced Parameters 1192------------------ 1193 1194To further illustrate deduced parameter support, consider the example of the 1195|def|_ function from Boost.Python_. Its signature is roughly as follows: 1196 1197.. parsed-literal:: 1198 1199 template < 1200 typename Function 1201 , typename KeywordExpression 1202 , typename CallPolicies 1203 > 1204 void def( 1205 // Required parameters 1206 char const\* name, Function func 1207 1208 // Optional, deduced parameters 1209 , char const\* docstring = "" 1210 , KeywordExpression keywords = no_keywords() 1211 , CallPolicies policies = default_call_policies() 1212 ); 1213 1214.. @ignore() 1215 1216Try not to be too distracted by the use of the term “keywords” in this 1217example: although it means something analogous in Boost.Python to what 1218it means in the Parameter library, for the purposes of this exercise 1219you can think of it as being completely different. 1220 1221When calling ``def``, only two arguments are required. The association 1222between any additional arguments and their parameters can be determined by the 1223types of the arguments actually passed, so the caller is neither required to 1224remember argument positions or explicitly specify parameter names for those 1225arguments. To generate this interface using ``BOOST_PARAMETER_FUNCTION``, we 1226need only enclose the deduced parameters in a ``(deduced …)`` clause, as 1227follows: 1228 1229.. parsed-literal:: 1230 1231 char const*& blank_char_ptr() 1232 { 1233 static char const* larr = ""; 1234 return larr; 1235 } 1236 1237 BOOST_PARAMETER_FUNCTION( 1238 (bool), def, tag, 1239 1240 (required (name, (char const\*)) (func,\*) ) // nondeduced 1241 1242 **(deduced** 1243 (optional 1244 (docstring, (char const\*), "") 1245 1246 (keywords 1247 // see [#is_keyword_expression]_ 1248 , \*(is_keyword_expression<boost::mpl::_>) 1249 , no_keywords() 1250 ) 1251 1252 (policies 1253 , \*( 1254 boost::mpl::eval_if< 1255 boost::is_convertible<boost::mpl::_,char const\*> 1256 , boost::mpl::false\_ 1257 , boost::mpl::if_< 1258 // see [#is_keyword_expression]_ 1259 is_keyword_expression<boost::mpl::_> 1260 , boost::mpl::false\_ 1261 , boost::mpl::true\_ 1262 > 1263 > 1264 ) 1265 , default_call_policies() 1266 ) 1267 ) 1268 **)** 1269 ) 1270 { 1271 *…* 1272 } 1273 1274.. @example.replace_emphasis('return true;') 1275 1276.. @example.prepend(''' 1277 #include <boost/parameter.hpp> 1278 1279 BOOST_PARAMETER_NAME(name) 1280 BOOST_PARAMETER_NAME(func) 1281 BOOST_PARAMETER_NAME(docstring) 1282 BOOST_PARAMETER_NAME(keywords) 1283 BOOST_PARAMETER_NAME(policies) 1284 1285 struct default_call_policies 1286 { 1287 }; 1288 1289 struct no_keywords 1290 { 1291 }; 1292 1293 struct keywords 1294 { 1295 }; 1296 1297 template <typename T> 1298 struct is_keyword_expression 1299 : boost::mpl::false_ 1300 { 1301 }; 1302 1303 template <> 1304 struct is_keyword_expression<keywords> 1305 : boost::mpl::true_ 1306 { 1307 }; 1308 1309 default_call_policies some_policies; 1310 1311 void f() 1312 { 1313 } 1314 1315 #include <boost/mpl/placeholders.hpp> 1316 #include <boost/mpl/if.hpp> 1317 #include <boost/mpl/eval_if.hpp> 1318 #include <boost/type_traits/is_convertible.hpp> 1319 1320 ''') 1321 1322.. Admonition:: Syntax Note 1323 1324 A ``(deduced …)`` clause always contains a ``(required …)`` and/or an 1325 ``(optional …)`` subclause, and must follow any ``(required …)`` or 1326 ``(optional …)`` clauses indicating nondeduced parameters at the outer 1327 level. 1328 1329With the declaration above, the following two calls are equivalent: 1330 1331.. parsed-literal:: 1332 1333 char const\* f_name = "f"; 1334 def( 1335 f_name 1336 , &f 1337 , **some_policies** 1338 , **"Documentation for f"** 1339 ); 1340 def( 1341 f_name 1342 , &f 1343 , **"Documentation for f"** 1344 , **some_policies** 1345 ); 1346 1347.. @example.prepend(''' 1348 int main() 1349 { 1350 ''') 1351 1352If the user wants to pass a ``policies`` argument that was also, for some 1353reason, convertible to ``char const*``, she can always specify the parameter 1354name explicitly, as follows: 1355 1356.. parsed-literal:: 1357 1358 def( 1359 f_name 1360 , &f 1361 , **_policies = some_policies** 1362 , "Documentation for f" 1363 ); 1364 1365.. @example.append('}') 1366.. @test('compile', howmany='all') 1367 1368The |deduced_cpp|_ and |deduced_dependent_predicate|_ test programs 1369demonstrate additional usage of deduced parameter support. 1370 1371.. _Boost.Python: ../../../python/doc/index.html 1372.. |def| replace:: ``def`` 1373.. _def: ../../../python/doc/v2/def.html 1374.. |deduced_cpp| replace:: deduced.cpp 1375.. _deduced_cpp: ../../test/deduced.cpp 1376.. |deduced_dependent_predicate| replace:: deduced_dependent_predicate.cpp 1377.. _deduced_dependent_predicate: ../../test/deduced_dependent_predicate.cpp 1378 1379Parameter-Dependent Return Types 1380-------------------------------- 1381 1382For some algorithms, the return type depends on at least one of the argument 1383types. However, there is one gotcha to avoid when encoding this return type 1384while using ``BOOST_PARAMETER_FUNCTION`` or other code generation macros. As 1385an example, given the following definitions:: 1386 1387 BOOST_PARAMETER_NAME(x) 1388 BOOST_PARAMETER_NAME(y) 1389 BOOST_PARAMETER_NAME(z) 1390 1391.. @ignore() 1392 1393Let our algorithm simply return one of its arguments. If we naïvely implement 1394its return type in terms of ``parameter::value_type``:: 1395 1396 BOOST_PARAMETER_FUNCTION( 1397 (typename parameter::value_type<Args,tag::y>::type), return_y, tag, 1398 (deduced 1399 (required 1400 (x, (std::map<char const*,std::string>)) 1401 (y, (char const*)) 1402 ) 1403 (optional 1404 (z, (int), 4) 1405 ) 1406 ) 1407 ) 1408 { 1409 return y; 1410 } 1411 1412.. @ignore() 1413 1414Then using ``return_y`` in any manner other than with positional arguments 1415will result in a compiler error:: 1416 1417 std::map<char const*,std::string> k2s; 1418 assert("foo" == return_y(2, k2s, "foo")); // error! 1419 1420.. @ignore() 1421 1422The problem is that even though ``y`` is a required parameter, 1423``BOOST_PARAMETER_FUNCTION`` will generate certain overloads for which the 1424argument pack type ``Args`` does not actually contain the keyword tag type 1425``tag::y``. The solution is to use SFINAE to preclude generation of those 1426overloads. Since ``parameter::value_type`` is a metafunction, our tool for 1427the job is ``lazy_enable_if``:: 1428 1429 BOOST_PARAMETER_FUNCTION( 1430 ( 1431 // Whenever using 'enable_if', 'disable_if', and so on, 1432 // do not add the 'typename' keyword in front. 1433 boost::lazy_enable_if< 1434 typename mpl::has_key<Args,tag::y>::type 1435 , parameter::value_type<Args,tag::y> 1436 > 1437 // Whenever using 'enable_if', 'disable_if', and so on, 1438 // do not add '::type' here. 1439 ), return_y, tag, 1440 (deduced 1441 (required 1442 (x, (std::map<char const*,std::string>)) 1443 (y, (char const*)) 1444 ) 1445 (optional 1446 (z, (int), 4) 1447 ) 1448 ) 1449 ) 1450 { 1451 return y; 1452 } 1453 1454.. @ignore() 1455 1456For a working demonstration, see |preprocessor_deduced_cpp|_. 1457 1458.. |preprocessor_deduced_cpp| replace:: preprocessor_deduced.cpp 1459.. _preprocessor_deduced_cpp: ../../test/preprocessor_deduced.cpp 1460 1461---------------------------------- 1462Parameter-Enabled Member Functions 1463---------------------------------- 1464 1465The ``BOOST_PARAMETER_MEMBER_FUNCTION`` and 1466``BOOST_PARAMETER_CONST_MEMBER_FUNCTION`` macros accept exactly the same 1467arguments as ``BOOST_PARAMETER_FUNCTION``, but are designed to be used within 1468the body of a class:: 1469 1470 BOOST_PARAMETER_NAME(arg1) 1471 BOOST_PARAMETER_NAME(arg2) 1472 1473 struct callable2 1474 { 1475 BOOST_PARAMETER_CONST_MEMBER_FUNCTION( 1476 (void), call, tag, (required (arg1,(int))(arg2,(int))) 1477 ) 1478 { 1479 std::cout << arg1 << ", " << arg2; 1480 std::cout << std::endl; 1481 } 1482 }; 1483 1484 #include <boost/core/lightweight_test.hpp> 1485 1486 int main() 1487 { 1488 callable2 c2; 1489 callable2 const& c2_const = c2; 1490 c2_const.call(1, 2); 1491 return boost::report_errors(); 1492 } 1493 1494.. @example.prepend(''' 1495 #include <boost/parameter.hpp> 1496 #include <iostream> 1497 using namespace boost::parameter; 1498 ''') 1499 1500.. @test('run') 1501 1502These macros don't directly allow a function's interface to be separated from 1503its implementation, but you can always forward arguments on to a separate 1504implementation function:: 1505 1506 struct callable2 1507 { 1508 BOOST_PARAMETER_CONST_MEMBER_FUNCTION( 1509 (void), call, tag, (required (arg1,(int))(arg2,(int))) 1510 ) 1511 { 1512 call_impl(arg1, arg2); 1513 } 1514 1515 private: 1516 void call_impl(int, int); // implemented elsewhere. 1517 }; 1518 1519.. @example.prepend(''' 1520 #include <boost/parameter.hpp> 1521 1522 BOOST_PARAMETER_NAME(arg1) 1523 BOOST_PARAMETER_NAME(arg2) 1524 using namespace boost::parameter; 1525 ''') 1526 1527.. @test('compile') 1528 1529Static Member Functions 1530======================= 1531 1532To expose a static member function, simply insert the keyword “``static``” 1533before the function name: 1534 1535.. parsed-literal:: 1536 1537 BOOST_PARAMETER_NAME(arg1) 1538 1539 struct somebody 1540 { 1541 BOOST_PARAMETER_MEMBER_FUNCTION( 1542 (void), **static** f, tag, (optional (arg1,(int),0)) 1543 ) 1544 { 1545 std::cout << arg1 << std::endl; 1546 } 1547 }; 1548 1549 #include <boost/core/lightweight_test.hpp> 1550 1551 int main() 1552 { 1553 somebody::f(); 1554 somebody::f(4); 1555 return boost::report_errors(); 1556 } 1557 1558.. @example.prepend(''' 1559 #include <boost/parameter.hpp> 1560 #include <iostream> 1561 using namespace boost::parameter; 1562 ''') 1563 1564.. @test('run') 1565 1566----------------------------------------- 1567Parameter-Enabled Function Call Operators 1568----------------------------------------- 1569 1570The ``BOOST_PARAMETER_FUNCTION_CALL_OPERATOR`` and 1571``BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR`` macros accept the same 1572arguments as the ``BOOST_PARAMETER_MEMBER_FUNCTION`` and 1573``BOOST_PARAMETER_CONST_MEMBER_FUNCTION`` macros except for the function name, 1574because these macros allow instances of the enclosing classes to be treated as 1575function objects:: 1576 1577 BOOST_PARAMETER_NAME(first_arg) 1578 BOOST_PARAMETER_NAME(second_arg) 1579 1580 struct callable2 1581 { 1582 BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR( 1583 (void), tag, (required (first_arg,(int))(second_arg,(int))) 1584 ) 1585 { 1586 std::cout << first_arg << ", "; 1587 std::cout << second_arg << std::endl; 1588 } 1589 }; 1590 1591 #include <boost/core/lightweight_test.hpp> 1592 1593 int main() 1594 { 1595 callable2 c2; 1596 callable2 const& c2_const = c2; 1597 c2_const(1, 2); 1598 return boost::report_errors(); 1599 } 1600 1601.. @example.prepend(''' 1602 #include <boost/parameter.hpp> 1603 #include <iostream> 1604 using namespace boost::parameter; 1605 ''') 1606 1607.. @test('run') 1608 1609------------------------------ 1610Parameter-Enabled Constructors 1611------------------------------ 1612 1613The lack of a “delegating constructor” feature in C++ 1614(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf) 1615limits somewhat the quality of interface this library can provide 1616for defining parameter-enabled constructors. The usual workaround 1617for a lack of constructor delegation applies: one must factor the 1618common logic into one or more base classes. 1619 1620Let's build a parameter-enabled constructor that simply prints its 1621arguments. The first step is to write a base class whose 1622constructor accepts a single argument known as an |ArgumentPack|_: 1623a bundle of references to the actual arguments, tagged with their 1624keywords. The values of the actual arguments are extracted from 1625the |ArgumentPack| by *indexing* it with keyword objects:: 1626 1627 BOOST_PARAMETER_NAME(name) 1628 BOOST_PARAMETER_NAME(index) 1629 1630 struct myclass_impl 1631 { 1632 template <typename ArgumentPack> 1633 myclass_impl(ArgumentPack const& args) 1634 { 1635 std::cout << "name = " << args[_name]; 1636 std::cout << "; index = " << args[_index | 42]; 1637 std::cout << std::endl; 1638 } 1639 }; 1640 1641.. @example.prepend(''' 1642 #include <boost/parameter.hpp> 1643 #include <iostream> 1644 ''') 1645 1646Note that the bitwise or (“\ ``|``\ ”) operator has a special meaning when 1647applied to keyword objects that are passed to an |ArgumentPack|\ 's indexing 1648operator: it is used to indicate a default value. In this case if there is no 1649``index`` parameter in the |ArgumentPack|, ``42`` will be used instead. 1650 1651Now we are ready to write the parameter-enabled constructor interface:: 1652 1653 struct myclass : myclass_impl 1654 { 1655 BOOST_PARAMETER_CONSTRUCTOR( 1656 myclass, (myclass_impl), tag 1657 , (required (name,*)) (optional (index,*)) 1658 ) // no semicolon 1659 }; 1660 1661Since we have supplied a default value for ``index`` but not for ``name``, 1662only ``name`` is required. We can exercise our new interface as follows:: 1663 1664 myclass x("bob", 3); // positional 1665 myclass y(_index = 12, _name = "sally"); // named 1666 myclass z("june"); // positional/defaulted 1667 1668.. @example.wrap(''' 1669 #include <boost/core/lightweight_test.hpp> 1670 1671 int main() { 1672 ''', ' return boost::report_errors(); }') 1673.. @test('run', howmany='all') 1674 1675For more on |ArgumentPack| manipulation, see the `Advanced Topics`_ section. 1676 1677--------------------------------- 1678Parameter-Enabled Class Templates 1679--------------------------------- 1680 1681In this section we'll use Boost.Parameter to build Boost.Python_\ 1682's `class_`_ template, whose “signature” is: 1683 1684.. parsed-literal:: 1685 1686 template < 1687 ValueType, BaseList = bases<> 1688 , HeldType = ValueType, Copyable = void 1689 > 1690 class class\_; 1691 1692.. @ignore() 1693 1694Only the first argument, ``ValueType``, is required. 1695 1696.. _class_: http://www.boost.org/libs/python/doc/v2/class.html#class_-spec 1697 1698Named Template Parameters 1699========================= 1700 1701First, we'll build an interface that allows users to pass arguments 1702positionally or by name: 1703 1704.. parsed-literal:: 1705 1706 struct B 1707 { 1708 virtual ~B() = 0; 1709 }; 1710 1711 struct D : B 1712 { 1713 ~D(); 1714 }; 1715 1716 class_< 1717 **class_type<B>** 1718 , **copyable<boost::noncopyable>** 1719 > …; 1720 1721 class_< 1722 **D** 1723 , **held_type<std::auto_ptr<D> >** 1724 , **base_list<bases<B> >** 1725 > …; 1726 1727.. @ignore() 1728 1729Template Keywords 1730----------------- 1731 1732The first step is to define keywords for each template parameter:: 1733 1734 namespace boost { namespace python { 1735 1736 BOOST_PARAMETER_TEMPLATE_KEYWORD(class_type) 1737 BOOST_PARAMETER_TEMPLATE_KEYWORD(base_list) 1738 BOOST_PARAMETER_TEMPLATE_KEYWORD(held_type) 1739 BOOST_PARAMETER_TEMPLATE_KEYWORD(copyable) 1740 }} 1741 1742.. @example.prepend('#include <boost/parameter.hpp>') 1743.. @test('compile') 1744 1745The declaration of the ``class_type`` keyword you see here is equivalent to:: 1746 1747 namespace boost { namespace python { 1748 namespace tag { 1749 1750 struct class_type; // keyword tag type 1751 } 1752 1753 template <typename T> 1754 struct class_type 1755 : parameter::template_keyword<tag::class_type,T> 1756 { 1757 }; 1758 }} 1759 1760.. @example.prepend('#include <boost/parameter.hpp>') 1761.. @test('compile') 1762 1763It defines a keyword tag type named ``tag::class_type`` and a 1764*parameter passing template* named ``class_type``. 1765 1766Class Template Skeleton 1767----------------------- 1768 1769The next step is to define the skeleton of our class template, which has three 1770optional parameters. Because the user may pass arguments in any order, we 1771don't know the actual identities of these parameters, so it would be premature 1772to use descriptive names or write out the actual default values for any of 1773them. Instead, we'll give them generic names and use the special type 1774``boost::parameter::void_`` as a default: 1775 1776.. parsed-literal:: 1777 1778 namespace boost { namespace python { 1779 1780 template < 1781 typename A0 1782 , typename A1 = boost::parameter::void\_ 1783 , typename A2 = boost::parameter::void\_ 1784 , typename A3 = boost::parameter::void\_ 1785 > 1786 struct class\_ 1787 { 1788 *…* 1789 }; 1790 }} 1791 1792.. @example.prepend('#include <boost/parameter.hpp>') 1793.. @example.replace_emphasis('') 1794.. @test('compile') 1795 1796Class Template Signatures 1797------------------------- 1798 1799Next, we need to build a type, known as a |ParameterSpec|_, describing the 1800“signature” of ``boost::python::class_``. A |ParameterSpec|_ enumerates the 1801required and optional parameters in their positional order, along with any 1802type requirements (note that it does *not* specify defaults -- those will be 1803dealt with separately):: 1804 1805 namespace boost { namespace python { 1806 1807 using boost::mpl::_; 1808 1809 typedef parameter::parameters< 1810 required<tag::class_type, boost::is_class<_> > 1811 , parameter::optional<tag::base_list, mpl::is_sequence<_> > 1812 , parameter::optional<tag::held_type> 1813 , parameter::optional<tag::copyable> 1814 > class_signature; 1815 }} 1816 1817.. @example.prepend(''' 1818 #include <boost/parameter.hpp> 1819 #include <boost/mpl/is_sequence.hpp> 1820 #include <boost/noncopyable.hpp> 1821 #include <boost/type_traits/is_class.hpp> 1822 #include <memory> 1823 1824 using namespace boost::parameter; 1825 1826 namespace boost { namespace python { 1827 1828 BOOST_PARAMETER_TEMPLATE_KEYWORD(class_type) 1829 BOOST_PARAMETER_TEMPLATE_KEYWORD(base_list) 1830 BOOST_PARAMETER_TEMPLATE_KEYWORD(held_type) 1831 BOOST_PARAMETER_TEMPLATE_KEYWORD(copyable) 1832 1833 template <typename B = int> 1834 struct bases 1835 { 1836 }; 1837 }} 1838 ''') 1839 1840.. |ParameterSpec| replace:: :concept:`ParameterSpec` 1841 1842.. _ParameterSpec: reference.html#parameterspec 1843 1844.. _binding_intro: 1845 1846Argument Packs and Parameter Extraction 1847--------------------------------------- 1848 1849Next, within the body of ``class_`` , we use the |ParameterSpec|\ 's 1850nested ``::bind< … >`` template to bundle the actual arguments into an 1851|ArgumentPack|_ type, and then use the library's ``value_type< … >`` 1852metafunction to extract “logical parameters”. ``value_type< … >`` is 1853a lot like ``binding< … >``, but no reference is added to the actual 1854argument type. Note that defaults are specified by passing it an 1855optional third argument:: 1856 1857 namespace boost { namespace python { 1858 1859 template < 1860 typename A0 1861 , typename A1 = boost::parameter::void_ 1862 , typename A2 = boost::parameter::void_ 1863 , typename A3 = boost::parameter::void_ 1864 > 1865 struct class_ 1866 { 1867 // Create ArgumentPack 1868 typedef typename class_signature::template bind< 1869 A0, A1, A2, A3 1870 >::type args; 1871 1872 // Extract first logical parameter. 1873 typedef typename parameter::value_type< 1874 args, tag::class_type 1875 >::type class_type; 1876 1877 typedef typename parameter::value_type< 1878 args, tag::base_list, bases<> 1879 >::type base_list; 1880 1881 typedef typename parameter::value_type< 1882 args, tag::held_type, class_type 1883 >::type held_type; 1884 1885 typedef typename parameter::value_type< 1886 args, tag::copyable, void 1887 >::type copyable; 1888 }; 1889 }} 1890 1891.. |ArgumentPack| replace:: :concept:`ArgumentPack` 1892.. _ArgumentPack: reference.html#argumentpack 1893 1894Exercising the Code So Far 1895========================== 1896 1897.. compound:: 1898 1899 Revisiting our original examples, :: 1900 1901 typedef boost::python::class_< 1902 class_type<B>, copyable<boost::noncopyable> 1903 > c1; 1904 1905 typedef boost::python::class_< 1906 D 1907 , held_type<std::auto_ptr<D> > 1908 , base_list<bases<B> > 1909 > c2; 1910 1911 .. @example.prepend(''' 1912 using boost::python::class_type; 1913 using boost::python::copyable; 1914 using boost::python::held_type; 1915 using boost::python::base_list; 1916 using boost::python::bases; 1917 1918 struct B 1919 { 1920 }; 1921 1922 struct D 1923 { 1924 }; 1925 ''') 1926 1927 we can now examine the intended parameters:: 1928 1929 BOOST_MPL_ASSERT((boost::is_same<c1::class_type, B>)); 1930 BOOST_MPL_ASSERT((boost::is_same<c1::base_list, bases<> >)); 1931 BOOST_MPL_ASSERT((boost::is_same<c1::held_type, B>)); 1932 BOOST_MPL_ASSERT(( 1933 boost::is_same<c1::copyable, boost::noncopyable> 1934 )); 1935 1936 BOOST_MPL_ASSERT((boost::is_same<c2::class_type, D>)); 1937 BOOST_MPL_ASSERT((boost::is_same<c2::base_list, bases<B> >)); 1938 BOOST_MPL_ASSERT(( 1939 boost::is_same<c2::held_type, std::auto_ptr<D> > 1940 )); 1941 BOOST_MPL_ASSERT((boost::is_same<c2::copyable, void>)); 1942 1943.. @test('compile', howmany='all') 1944 1945Deduced Template Parameters 1946=========================== 1947 1948To apply a deduced parameter interface here, we need only make the type 1949requirements a bit tighter so the ``held_type`` and ``copyable`` parameters 1950can be crisply distinguished from the others. Boost.Python_ does this by 1951requiring that ``base_list`` be a specialization of its ``bases< … >`` 1952template (as opposed to being any old MPL sequence) and by requiring that 1953``copyable``, if explicitly supplied, be ``boost::noncopyable``. One easy way 1954of identifying specializations of ``bases< … >`` is to derive them all from 1955the same class, as an implementation detail: 1956 1957.. parsed-literal:: 1958 1959 namespace boost { namespace python { 1960 namespace detail { 1961 1962 struct bases_base 1963 { 1964 }; 1965 } 1966 1967 template < 1968 typename A0 = void, typename A1 = void, typename A2 = void *…* 1969 > 1970 struct bases **: detail::bases_base** 1971 { 1972 }; 1973 }} 1974 1975.. @example.replace_emphasis('') 1976.. @example.prepend(''' 1977 #include <boost/parameter.hpp> 1978 #include <boost/mpl/is_sequence.hpp> 1979 #include <boost/noncopyable.hpp> 1980 #include <memory> 1981 1982 using namespace boost::parameter; 1983 using boost::mpl::_; 1984 1985 namespace boost { namespace python { 1986 1987 BOOST_PARAMETER_TEMPLATE_KEYWORD(class_type) 1988 BOOST_PARAMETER_TEMPLATE_KEYWORD(base_list) 1989 BOOST_PARAMETER_TEMPLATE_KEYWORD(held_type) 1990 BOOST_PARAMETER_TEMPLATE_KEYWORD(copyable) 1991 }} 1992 ''') 1993 1994Now we can rewrite our signature to make all three optional parameters 1995deducible:: 1996 1997 typedef parameter::parameters< 1998 required<tag::class_type, is_class<_> > 1999 2000 , parameter::optional< 2001 deduced<tag::base_list> 2002 , is_base_and_derived<detail::bases_base,_> 2003 > 2004 2005 , parameter::optional< 2006 deduced<tag::held_type> 2007 , mpl::not_< 2008 mpl::or_< 2009 is_base_and_derived<detail::bases_base,_> 2010 , is_same<noncopyable,_> 2011 > 2012 > 2013 > 2014 2015 , parameter::optional< 2016 deduced<tag::copyable> 2017 , is_same<noncopyable,_> 2018 > 2019 2020 > class_signature; 2021 2022.. @example.prepend(''' 2023 #include <boost/type_traits/is_class.hpp> 2024 namespace boost { namespace python { 2025 ''') 2026 2027.. @example.append(''' 2028 template < 2029 typename A0 2030 , typename A1 = boost::parameter::void_ 2031 , typename A2 = boost::parameter::void_ 2032 , typename A3 = boost::parameter::void_ 2033 > 2034 struct class_ 2035 { 2036 // Create ArgumentPack 2037 typedef typename class_signature::bind< 2038 A0, A1, A2, A3 2039 >::type args; 2040 2041 // Extract first logical parameter. 2042 typedef typename parameter::value_type< 2043 args, tag::class_type 2044 >::type class_type; 2045 2046 typedef typename parameter::value_type< 2047 args, tag::base_list, bases<> 2048 >::type base_list; 2049 2050 typedef typename parameter::value_type< 2051 args, tag::held_type, class_type 2052 >::type held_type; 2053 2054 typedef typename parameter::value_type< 2055 args, tag::copyable, void 2056 >::type copyable; 2057 }; 2058 }} 2059 ''') 2060 2061It may seem like we've added a great deal of complexity, but the benefits to 2062our users are greater. Our original examples can now be written without 2063explicit parameter names: 2064 2065.. parsed-literal:: 2066 2067 typedef boost::python::class_<**B**, **boost::noncopyable**> c1; 2068 2069 typedef boost::python::class_< 2070 **D**, **std::auto_ptr<D>**, **bases<B>** 2071 > c2; 2072 2073.. @example.prepend(''' 2074 struct B 2075 { 2076 }; 2077 2078 struct D 2079 { 2080 }; 2081 2082 using boost::python::bases; 2083 ''') 2084 2085.. @example.append(''' 2086 BOOST_MPL_ASSERT((boost::is_same<c1::class_type, B>)); 2087 BOOST_MPL_ASSERT((boost::is_same<c1::base_list, bases<> >)); 2088 BOOST_MPL_ASSERT((boost::is_same<c1::held_type, B>)); 2089 BOOST_MPL_ASSERT(( 2090 boost::is_same<c1::copyable, boost::noncopyable> 2091 )); 2092 2093 BOOST_MPL_ASSERT((boost::is_same<c2::class_type, D>)); 2094 BOOST_MPL_ASSERT((boost::is_same<c2::base_list, bases<B> >)); 2095 BOOST_MPL_ASSERT(( 2096 boost::is_same<c2::held_type, std::auto_ptr<D> > 2097 )); 2098 BOOST_MPL_ASSERT((boost::is_same<c2::copyable, void>)); 2099 ''') 2100 2101.. @test('compile', howmany='all') 2102 2103=============== 2104Advanced Topics 2105=============== 2106 2107At this point, you should have a good grasp of the basics. In this section 2108we'll cover some more esoteric uses of the library. 2109 2110------------------------- 2111Fine-Grained Name Control 2112------------------------- 2113 2114If you don't like the leading-underscore naming convention used to refer to 2115keyword objects, or you need the name ``tag`` for something other than the 2116keyword type namespace, there's another way to use ``BOOST_PARAMETER_NAME``: 2117 2118.. parsed-literal:: 2119 2120 BOOST_PARAMETER_NAME( 2121 **(** 2122 *object-name* 2123 **,** *tag-namespace* 2124 **)** *parameter-name* 2125 ) 2126 2127.. @ignore() 2128 2129Here is a usage example: 2130 2131.. parsed-literal:: 2132 2133 BOOST_PARAMETER_NAME( 2134 ( 2135 **pass_foo**, **keywords** 2136 ) **foo** 2137 ) 2138 2139 BOOST_PARAMETER_FUNCTION( 2140 (int), f, 2141 **keywords**, (required (**foo**, \*)) 2142 ) 2143 { 2144 return **foo** + 1; 2145 } 2146 2147 int x = f(**pass_foo** = 41); 2148 2149.. @example.prepend('#include <boost/parameter.hpp>') 2150.. @example.append(''' 2151 int main() 2152 { 2153 return 0; 2154 } 2155 ''') 2156.. @test('run') 2157 2158Before you use this more verbose form, however, please read the section on 2159`best practices for keyword object naming`__. 2160 2161__ `Keyword Naming`_ 2162 2163---------------------- 2164More |ArgumentPack|\ s 2165---------------------- 2166 2167We've already seen |ArgumentPack|\ s when we looked at 2168`parameter-enabled constructors`_ and `class templates`__. As you 2169might have guessed, |ArgumentPack|\ s actually lie at the heart of 2170everything this library does; in this section we'll examine ways to 2171build and manipulate them more effectively. 2172 2173__ binding_intro_ 2174 2175Building |ArgumentPack|\ s 2176========================== 2177 2178The simplest |ArgumentPack| is the result of assigning into a keyword object:: 2179 2180 BOOST_PARAMETER_NAME(index) 2181 2182 template <typename ArgumentPack> 2183 int print_index(ArgumentPack const& args) 2184 { 2185 std::cout << "index = " << args[_index]; 2186 std::cout << std::endl; 2187 return 0; 2188 } 2189 2190 int x = print_index(_index = 3); // prints "index = 3" 2191 2192.. @example.prepend(''' 2193 #include <boost/parameter.hpp> 2194 #include <iostream> 2195 ''') 2196 2197Also, |ArgumentPack|\ s can be composed using the comma operator. The extra 2198parentheses below are used to prevent the compiler from seeing two separate 2199arguments to ``print_name_and_index``:: 2200 2201 BOOST_PARAMETER_NAME(name) 2202 2203 template <typename ArgumentPack> 2204 int print_name_and_index(ArgumentPack const& args) 2205 { 2206 std::cout << "name = " << args[_name]; 2207 std::cout << "; "; 2208 return print_index(args); 2209 } 2210 2211 int y = print_name_and_index((_index = 3, _name = "jones")); 2212 2213The |compose_cpp|_ test program shows more examples of this feature. 2214 2215To build an |ArgumentPack| with positional arguments, we can use a 2216|ParameterSpec|_. As introduced described in the section on `Class Template 2217Signatures`_, a |ParameterSpec| describes the positional order of parameters 2218and any associated type requirements. Just as we can build an |ArgumentPack| 2219*type* with its nested ``::bind< … >`` template, we can build an 2220|ArgumentPack| *object* by invoking its function call operator: 2221 2222.. parsed-literal:: 2223 2224 parameter::parameters< 2225 required<tag::\ name, is_convertible<_,char const*> > 2226 , optional<tag::\ index, is_convertible<_,int> > 2227 > spec; 2228 2229 char const sam[] = "sam"; 2230 int twelve = 12; 2231 2232 int z0 = print_name_and_index( 2233 **spec(** sam, twelve **)** 2234 ); 2235 2236 int z1 = print_name_and_index( 2237 **spec(** _index=12, _name="sam" **)** 2238 ); 2239 2240.. @example.prepend(''' 2241 namespace parameter = boost::parameter; 2242 using parameter::required; 2243 using parameter::optional; 2244 using boost::is_convertible; 2245 using boost::mpl::_; 2246 ''') 2247 2248.. @example.append(''' 2249 int main() 2250 { 2251 return 0; 2252 } 2253 ''') 2254 2255.. @test('run', howmany='all') 2256 2257Extracting Parameter Types 2258========================== 2259 2260If we want to know the types of the arguments passed to 2261``print_name_and_index``, we have a couple of options. The 2262simplest and least error-prone approach is to forward them to a 2263function template and allow *it* to do type deduction:: 2264 2265 BOOST_PARAMETER_NAME(name) 2266 BOOST_PARAMETER_NAME(index) 2267 2268 template <typename Name, typename Index> 2269 int deduce_arg_types_impl(Name&& name, Index&& index) 2270 { 2271 // we know the types 2272 Name&& n2 = boost::forward<Name>(name); 2273 Index&& i2 = boost::forward<Index>(index); 2274 return index; 2275 } 2276 2277 template <typename ArgumentPack> 2278 int deduce_arg_types(ArgumentPack const& args) 2279 { 2280 return deduce_arg_types_impl(args[_name], args[_index | 42]); 2281 } 2282 2283.. @example.prepend(''' 2284 #include <boost/parameter.hpp> 2285 ''') 2286 2287.. @example.append(''' 2288 #include <boost/core/lightweight_test.hpp> 2289 2290 int main() 2291 { 2292 int a1 = deduce_arg_types((_name = "foo")); 2293 int a2 = deduce_arg_types((_name = "foo", _index = 3)); 2294 BOOST_TEST_EQ(a1, 42); 2295 BOOST_TEST_EQ(a2, 3); 2296 return boost::report_errors(); 2297 } 2298 ''') 2299 2300.. @test('run') 2301 2302Occasionally one needs to deduce argument types without an extra layer of 2303function call. For example, suppose we wanted to return twice the value of 2304the ``index`` parameter? In that case we can use the ``value_type< … >`` 2305metafunction introduced `earlier`__:: 2306 2307 BOOST_PARAMETER_NAME(index) 2308 2309 template <typename ArgumentPack> 2310 typename boost::parameter::value_type<ArgumentPack,tag::index,int>::type 2311 twice_index(ArgumentPack const& args) 2312 { 2313 return 2 * args[_index | 42]; 2314 } 2315 2316.. @example.prepend(''' 2317 #include <boost/parameter.hpp> 2318 ''') 2319 2320.. @example.append(''' 2321 #include <boost/core/lightweight_test.hpp> 2322 2323 int main() 2324 { 2325 int six = twice_index(_index = 3); 2326 BOOST_TEST_EQ(six, 6); 2327 return boost::report_errors(); 2328 } 2329 ''') 2330 2331.. @test('run', howmany='all') 2332 2333Note that if we had used ``binding< … >`` rather than ``value_type< … >``, we 2334would end up returning a reference to the temporary created in the ``2 * …`` 2335expression. 2336 2337__ binding_intro_ 2338 2339Lazy Default Computation 2340======================== 2341 2342When a default value is expensive to compute, it would be preferable to avoid 2343it until we're sure it's absolutely necessary. ``BOOST_PARAMETER_FUNCTION`` 2344takes care of that problem for us, but when using |ArgumentPack|\ s 2345explicitly, we need a tool other than ``operator|``:: 2346 2347 BOOST_PARAMETER_NAME(s1) 2348 BOOST_PARAMETER_NAME(s2) 2349 BOOST_PARAMETER_NAME(s3) 2350 2351 template <typename ArgumentPack> 2352 std::string f(ArgumentPack const& args) 2353 { 2354 std::string const& s1 = args[_s1]; 2355 std::string const& s2 = args[_s2]; 2356 typename parameter::binding< 2357 ArgumentPack,tag::s3,std::string 2358 >::type s3 = args[_s3 | (s1 + s2)]; // always constructs s1 + s2 2359 return s3; 2360 } 2361 2362 std::string x = f(( 2363 _s1="hello,", _s2=" world", _s3="hi world" 2364 )); 2365 2366.. @example.prepend(''' 2367 #include <boost/parameter.hpp> 2368 #include <string> 2369 2370 namespace parameter = boost::parameter; 2371 ''') 2372 2373.. @example.append(''' 2374 int main() 2375 { 2376 return 0; 2377 } 2378 ''') 2379 2380.. @test('run') 2381 2382In the example above, the string ``"hello, world"`` is constructed despite the 2383fact that the user passed us a value for ``s3``. To remedy that, we can 2384compute the default value *lazily* (that is, only on demand), by using 2385``boost::bind()`` to create a function object. 2386 2387.. danielw: I'm leaving the text below in the source, because we might 2388.. want to change back to it after 1.34, and if I remove it now we 2389.. might forget about it. 2390 2391.. by combining the logical-or (“``||``”) operator 2392.. with a function object built by the Boost Lambda_ library: [#bind]_ 2393 2394.. parsed-literal:: 2395 2396 typename parameter::binding< 2397 ArgumentPack,tag::s3,std::string 2398 >::type s3 = args[ 2399 _s3 **|| boost::bind( 2400 std::plus<std::string>(), boost::ref(s1), boost::ref(s2) 2401 )** 2402 ]; 2403 2404.. @example.prepend(''' 2405 #include <boost/bind.hpp> 2406 #include <boost/ref.hpp> 2407 #include <boost/parameter.hpp> 2408 #include <string> 2409 #include <functional> 2410 2411 namespace parameter = boost::parameter; 2412 2413 BOOST_PARAMETER_NAME(s1) 2414 BOOST_PARAMETER_NAME(s2) 2415 BOOST_PARAMETER_NAME(s3) 2416 2417 template <typename ArgumentPack> 2418 std::string f(ArgumentPack const& args) 2419 { 2420 std::string const& s1 = args[_s1]; 2421 std::string const& s2 = args[_s2]; 2422 ''') 2423 2424.. @example.append(''' 2425 return s3; 2426 } 2427 2428 std::string x = f((_s1="hello,", _s2=" world", _s3="hi world")); 2429 2430 int main() 2431 { 2432 return 0; 2433 } 2434 ''') 2435 2436.. @test('run') 2437 2438.. .. _Lambda: ../../../lambda/index.html 2439 2440.. sidebar:: Mnemonics 2441 2442 To remember the difference between ``|`` and ``||``, recall that ``||`` 2443 normally uses short-circuit evaluation: its second argument is only 2444 evaluated if its first argument is ``false``. Similarly, in 2445 ``color_map[param || f]``, ``f`` is only invoked if no ``color_map`` 2446 argument was supplied. 2447 2448The expression ``bind(std::plus<std::string>(), ref(s1), ref(s2))`` yields a 2449*function object* that, when invoked, adds the two strings together. That 2450function will only be invoked if no ``s3`` argument is supplied by the caller. 2451 2452.. The expression ``lambda::var(s1) + lambda::var(s2)`` yields a 2453.. *function object* that, when invoked, adds the two strings 2454.. together. That function will only be invoked if no ``s3`` argument 2455.. is supplied by the caller. 2456 2457============== 2458Best Practices 2459============== 2460 2461By now you should have a fairly good idea of how to use the Parameter 2462library. This section points out a few more-marginal issues that will help 2463you use the library more effectively. 2464 2465-------------- 2466Keyword Naming 2467-------------- 2468 2469``BOOST_PARAMETER_NAME`` prepends a leading underscore to the names of all our 2470keyword objects in order to avoid the following usually-silent bug: 2471 2472.. parsed-literal:: 2473 2474 namespace people 2475 { 2476 namespace tag 2477 { 2478 struct name 2479 { 2480 typedef boost::parameter::forward_reference qualifier; 2481 }; 2482 2483 struct age 2484 { 2485 typedef boost::parameter::forward_reference qualifier; 2486 }; 2487 } 2488 2489 namespace // unnamed 2490 { 2491 boost::parameter::keyword<tag::name>& **name** 2492 = boost::parameter::keyword<tag::name>::instance; 2493 boost::parameter::keyword<tag::age>& **age** 2494 = boost::parameter::keyword<tag::age>::instance; 2495 } 2496 2497 BOOST_PARAMETER_FUNCTION( 2498 (void), g, tag, (optional (name, \*, "bob")(age, \*, 42)) 2499 ) 2500 { 2501 std::cout << name << ":" << age; 2502 } 2503 2504 void f(int age) 2505 { 2506 :vellipsis:`\ 2507 . 2508 . 2509 . 2510 ` 2511 g(**age** = 3); // whoops! 2512 } 2513 } 2514 2515.. @ignore() 2516 2517Although in the case above, the user was trying to pass the value ``3`` as the 2518``age`` parameter to ``g``, what happened instead was that ``f``\ 's ``age`` 2519argument got reassigned the value 3, and was then passed as a positional 2520argument to ``g``. Since ``g``'s first positional parameter is ``name``, the 2521default value for ``age`` is used, and g prints ``3:42``. Our leading 2522underscore naming convention makes this problem less likely to occur. 2523 2524In this particular case, the problem could have been detected if f's ``age`` 2525parameter had been made ``const``, which is always a good idea whenever 2526possible. Finally, we recommend that you use an enclosing namespace for all 2527your code, but particularly for names with leading underscores. If we were to 2528leave out the ``people`` namespace above, names in the global namespace 2529beginning with leading underscores—which are reserved to your C++ 2530compiler—might become irretrievably ambiguous with those in our 2531unnamed namespace. 2532 2533---------- 2534Namespaces 2535---------- 2536 2537In our examples we've always declared keyword objects in (an unnamed namespace 2538within) the same namespace as the Boost.Parameter-enabled functions using 2539those keywords: 2540 2541.. parsed-literal:: 2542 2543 namespace lib { 2544 2545 **BOOST_PARAMETER_NAME(name) 2546 BOOST_PARAMETER_NAME(index)** 2547 2548 BOOST_PARAMETER_FUNCTION( 2549 (int), f, tag, 2550 (optional (name,*,"bob")(index,(int),1)) 2551 ) 2552 { 2553 std::cout << name << ":" << index; 2554 std::cout << std::endl; 2555 return index; 2556 } 2557 } 2558 2559.. @example.prepend(''' 2560 #include <boost/parameter.hpp> 2561 #include <iostream> 2562 ''') 2563.. @namespace_setup = str(example) 2564.. @ignore() 2565 2566Users of these functions have a few choices: 2567 25681. Full qualification: 2569 2570 .. parsed-literal:: 2571 2572 int x = **lib::**\ f( 2573 **lib::**\ _name = "jill" 2574 , **lib::**\ _index = 1 2575 ); 2576 2577 This approach is more verbose than many users would like. 2578 2579.. @example.prepend(namespace_setup) 2580.. @example.append('int main() { return 0; }') 2581.. @test('run') 2582 25832. Make keyword objects available through *using-declarations*: 2584 2585 .. parsed-literal:: 2586 2587 **using lib::_name; 2588 using lib::_index;** 2589 2590 int x = lib::f(_name = "jill", _index = 1); 2591 2592 This version is much better at the actual call site, but the 2593 *using-declarations* themselves can be verbose and hard to manage. 2594 2595.. @example.prepend(namespace_setup) 2596.. @example.append('int main() { return 0; }') 2597.. @test('run') 2598 25993. Bring in the entire namespace with a *using-directive*: 2600 2601 .. parsed-literal:: 2602 2603 **using namespace lib;** 2604 int x = **f**\ (_name = "jill", _index = 3); 2605 2606 This option is convenient, but it indiscriminately makes the *entire* 2607 contents of ``lib`` available without qualification. 2608 2609.. @example.prepend(namespace_setup) 2610.. @example.append('int main() { return 0; }') 2611.. @test('run') 2612 2613If we add an additional namespace around keyword declarations, though, we can 2614give users more control: 2615 2616.. parsed-literal:: 2617 2618 namespace lib { 2619 **namespace keywords {** 2620 2621 BOOST_PARAMETER_NAME(name) 2622 BOOST_PARAMETER_NAME(index) 2623 **}** 2624 2625 BOOST_PARAMETER_FUNCTION( 2626 (int), f, **keywords::**\ tag, 2627 (optional (name,*,"bob")(index,(int),1)) 2628 ) 2629 { 2630 std::cout << name << ":" << index; 2631 std::cout << std::endl; 2632 return index; 2633 } 2634 } 2635 2636.. @example.prepend(''' 2637 #include <boost/parameter.hpp> 2638 #include <iostream> 2639 ''') 2640 2641Now users need only a single *using-directive* to bring in just the names of 2642all keywords associated with ``lib``: 2643 2644.. parsed-literal:: 2645 2646 **using namespace lib::keywords;** 2647 int y = lib::f(_name = "bob", _index = 2); 2648 2649.. @example.append('int main() { return 0; }') 2650.. @test('run', howmany='all') 2651 2652------------- 2653Documentation 2654------------- 2655 2656The interface idioms enabled by Boost.Parameter are completely new (to C++), 2657and as such are not served by pre-existing documentation conventions. 2658 2659.. Note:: This space is empty because we haven't settled on any best practices 2660 yet. We'd be very pleased to link to your documentation if you've got a 2661 style that you think is worth sharing. 2662 2663========================== 2664Portability Considerations 2665========================== 2666 2667Use the `regression test results`_ for the latest Boost release of 2668the Parameter library to see how it fares on your favorite 2669compiler. Additionally, you may need to be aware of the following 2670issues and workarounds for particular compilers. 2671 2672.. _`regression test results`: http\://www.boost.org/regression/release/user/parameter.html 2673 2674-------------------------- 2675Perfect Forwarding Support 2676-------------------------- 2677 2678If your compiler supports `perfect forwarding`_, then the Parameter library 2679will ``#define`` the macro ``BOOST_PARAMETER_HAS_PERFECT_FORWARDING`` unless 2680you disable it manually. If your compiler does not provide this support, then 2681``parameter::parameters::operator()`` will treat rvalue references as lvalue 2682``const`` references to work around the `forwarding problem`_, so in certain 2683cases you must wrap |boost_ref|_ or |std_ref|_ around any arguments that will 2684be bound to out parameters. The |evaluate_category|_ and 2685|preprocessor_eval_category|_ test programs demonstrate this support. 2686 2687.. _`perfect forwarding`: http\://www.justsoftwaresolutions.co.uk/cplusplus/rvalue_references_and_perfect_forwarding.html 2688.. _`forwarding problem`: http\://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm 2689.. |boost_ref| replace:: ``boost::ref`` 2690.. _boost_ref: ../../../core/doc/html/core/ref.html 2691.. |std_ref| replace:: ``std::ref`` 2692.. _std_ref: http://en.cppreference.com/w/cpp/utility/functional/ref 2693.. |evaluate_category| replace:: evaluate_category.cpp 2694.. _evaluate_category: ../../test/evaluate_category.cpp 2695.. |preprocessor_eval_category| replace:: preprocessor_eval_category.cpp 2696.. _preprocessor_eval_category: ../../test/preprocessor_eval_category.cpp 2697 2698------------------ 2699Boost.MP11 Support 2700------------------ 2701 2702If your compiler is sufficiently compliant with the C++11 standard, then the 2703Parameter library will ``#define`` the macro ``BOOST_PARAMETER_CAN_USE_MP11`` 2704unless you disable it manually. The |singular_cpp|_, |compose_cpp|_, 2705|optional_deduced_sfinae_cpp|_, and |deduced_dep_pred_cpp|_ test programs 2706demonstrate support for `Boost.MP11`_. 2707 2708.. _`Boost.MP11`: ../../../mp11/doc/html/mp11.html 2709.. |singular_cpp| replace:: singular.cpp 2710.. _singular_cpp: ../../test/singular.cpp 2711.. |optional_deduced_sfinae_cpp| replace:: optional_deduced_sfinae.cpp 2712.. _optional_deduced_sfinae_cpp: ../../test/optional_deduced_sfinae.cpp 2713.. |deduced_dep_pred_cpp| replace:: deduced_dependent_predicate.cpp 2714.. _deduced_dep_pred_cpp: ../../test/deduced_dependent_predicate.cpp 2715 2716----------------- 2717No SFINAE Support 2718----------------- 2719 2720Some older compilers don't support SFINAE. If your compiler meets that 2721criterion, then Boost headers will ``#define`` the preprocessor symbol 2722``BOOST_NO_SFINAE``, and parameter-enabled functions won't be removed 2723from the overload set based on their signatures. The |sfinae_cpp|_ and 2724|optional_deduced_sfinae|_ test programs demonstrate SFINAE support. 2725 2726.. |sfinae_cpp| replace:: sfinae.cpp 2727.. _sfinae_cpp: ../../test/sfinae.cpp 2728.. |optional_deduced_sfinae| replace:: optional_deduced_sfinae.cpp 2729.. _optional_deduced_sfinae: ../../test/optional_deduced_sfinae.cpp 2730 2731--------------------------- 2732No Support for |result_of|_ 2733--------------------------- 2734 2735.. |result_of| replace:: ``result_of`` 2736 2737.. _result_of: ../../../utility/utility.htm#result_of 2738 2739`Lazy default computation`_ relies on the |result_of| class template to 2740compute the types of default arguments given the type of the function object 2741that constructs them. On compilers that don't support |result_of|, 2742``BOOST_NO_RESULT_OF`` will be ``#define``\ d, and the compiler will expect 2743the function object to contain a nested type name, ``result_type``, that 2744indicates its return type when invoked without arguments. To use an ordinary 2745function as a default generator on those compilers, you'll need to wrap it in 2746a class that provides ``result_type`` as a ``typedef`` and invokes the 2747function via its ``operator()``. 2748 2749.. 2750 Can't Declare |ParameterSpec| via ``typedef`` 2751 ============================================= 2752 2753 In principle you can declare a |ParameterSpec| as a ``typedef`` for a 2754 specialization of ``parameters<…>``, but Microsoft Visual C++ 6.x has been 2755 seen to choke on that usage. The workaround is to use inheritance and 2756 declare your |ParameterSpec| as a class: 2757 2758 .. parsed-literal:: 2759 2760 **struct dfs_parameters 2761 :** parameter::parameters< 2762 tag::graph, tag::visitor, tag::root_vertex 2763 , tag::index_map, tag::color_map 2764 > 2765 **{ 2766 };** 2767 2768 Default Arguments Unsupported on Nested Templates 2769 ============================================= 2770 2771 As of this writing, Borland compilers don't support the use of default 2772 template arguments on member class templates. As a result, you have to 2773 supply ``BOOST_PARAMETER_MAX_ARITY`` arguments to every use of 2774 ``parameters<…>::match``. Since the actual defaults used are unspecified, 2775 the workaround is to use |BOOST_PARAMETER_MATCH|_ to declare default 2776 arguments for SFINAE. 2777 2778 .. |BOOST_PARAMETER_MATCH| replace:: ``BOOST_PARAMETER_MATCH`` 2779 2780-------------------------------------------------- 2781Compiler Can't See References In Unnamed Namespace 2782-------------------------------------------------- 2783 2784If you use Microsoft Visual C++ 6.x, you may find that the compiler has 2785trouble finding your keyword objects. This problem has been observed, but 2786only on this one compiler, and it disappeared as the test code evolved, so 2787we suggest you use it only as a last resort rather than as a preventative 2788measure. The solution is to add *using-declarations* to force the names 2789to be available in the enclosing namespace without qualification:: 2790 2791 namespace graphs { 2792 2793 using graphs::graph; 2794 using graphs::visitor; 2795 using graphs::root_vertex; 2796 using graphs::index_map; 2797 using graphs::color_map; 2798 } 2799 2800============== 2801Python Binding 2802============== 2803 2804.. _python: python.html 2805 2806Follow `this link`__ for documentation on how to expose 2807Boost.Parameter-enabled functions to Python with `Boost.Python`_. 2808 2809__ ../../../parameter_python/doc/html/index.html 2810 2811========= 2812Reference 2813========= 2814 2815.. _reference: reference.html 2816 2817Follow `this link`__ to the Boost.Parameter reference documentation. 2818 2819__ reference.html 2820 2821======== 2822Glossary 2823======== 2824 2825.. _arguments: 2826 2827------------------------------- 2828Argument (or “actual argument”) 2829------------------------------- 2830 2831the value actually passed to a function or class template. 2832 2833.. _parameter: 2834 2835--------------------------------- 2836Parameter (or “formal parameter”) 2837--------------------------------- 2838 2839the name used to refer to an argument within a function or class 2840template. For example, the value of ``f``'s *parameter* ``x`` is given by the 2841*argument* ``3``: 2842 2843.. parsed-literal:: 2844 2845 int f(int x) { return x + 1; } 2846 int y = f(3); 2847 2848================ 2849Acknowledgements 2850================ 2851 2852The authors would like to thank all the Boosters who participated in the 2853review of this library and its documentation, most especially our review 2854manager, Doug Gregor. 2855 2856-------------------------- 2857 2858.. [#old_interface] As of Boost 1.33.0 the Graph library was still using an 2859 `older named parameter mechanism`__, but there are plans to change it to 2860 use Boost.Parameter (this library) in an upcoming release, while keeping 2861 the old interface available for backward-compatibility. 2862 2863__ ../../../graph/doc/bgl_named_params.html 2864 2865.. [#odr] The **One Definition Rule** says that any given entity in a C++ 2866 program must have the same definition in all translation units (object 2867 files) that make up a program. 2868 2869.. [#vertex_descriptor] If you're not familiar with the Boost Graph Library, 2870 don't worry about the meaning of any Graph-library-specific details you 2871 encounter. In this case you could replace all mentions of vertex 2872 descriptor types with ``int`` in the text, and your understanding of the 2873 Parameter library wouldn't suffer. 2874 2875.. [#ConceptsTS] This is a major motivation behind `C++20 constraints`_. 2876 2877.. _`C++20 constraints`: http://en.cppreference.com/w/cpp/language/constraints 2878 2879.. .. [#bind] The Lambda library is known not to work on `some 2880.. less-conformant compilers`__. When using one of those you could 2881.. use `Boost.Bind`_ to generate the function object\:\: 2882 2883.. boost\:\:bind(std\:\:plus<std\:\:string>(),s1,s2) 2884 2885.. [#is_keyword_expression] Here we're assuming there's a predicate 2886 metafunction ``is_keyword_expression`` that can be used to identify 2887 models of Boost.Python's KeywordExpression concept. 2888 2889.. .. __ http://www.boost.org/regression/release/user/lambda.html 2890.. _Boost.Bind: ../../../bind/index.html 2891 2892.. [#using] You can always give the illusion that the function 2893 lives in an outer namespace by applying a *using-declaration*:: 2894 2895 namespace foo_overloads { 2896 2897 // foo declarations here 2898 void foo() { ... } 2899 ... 2900 } 2901 using foo_overloads::foo; 2902 2903 This technique for avoiding unintentional argument-dependent lookup is due 2904 to Herb Sutter. 2905 2906.. [#sfinae] This capability depends on your compiler's support for 2907 SFINAE. **SFINAE**: **S**\ ubstitution **F**\ ailure **I**\ s **N**\ ot 2908 **A**\ n **E**\ rror. If type substitution during the instantiation of a 2909 function template results in an invalid type, no compilation error is 2910 emitted; instead the overload is removed from the overload set. By 2911 producing an invalid type in the function signature depending on the 2912 result of some condition, we can decide whether or not an overload is 2913 considered during overload resolution. The technique is formalized in the 2914 |enable_if|_ utility. Most recent compilers support SFINAE; on compilers 2915 that don't support it, the Boost config library will ``#define`` the 2916 symbol ``BOOST_NO_SFINAE``. See 2917 http://www.semantics.org/once_weakly/w02_SFINAE.pdf for more information 2918 on SFINAE. 2919 2920.. |enable_if| replace:: ``enable_if`` 2921.. _enable_if: ../../../core/doc/html/core/enable_if.html 2922 2923 2924