1+++++++++++++++++++++++++++++++++++++++++++++++++ 2 The 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 15 that can accept arguments by name: 16 17 .. parsed-literal:: 18 19 new_window("alert", **_width=10**, **_titlebar=false**); 20 21 smart_ptr< 22 Foo 23 , **deleter<Deallocate<Foo> >** 24 , **copy_policy<DeepCopy>** > p(new Foo); 25 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. 31 32.. @jam_prefix.append(''' 33 project test : requirements <include>. <implicit-dependency>/boost//headers ;''') 34 35.. @example.prepend(''' 36 #include <boost/parameter.hpp> 37 38 namespace test 39 { 40 BOOST_PARAMETER_NAME(title) 41 BOOST_PARAMETER_NAME(width) 42 BOOST_PARAMETER_NAME(titlebar) 43 44 BOOST_PARAMETER_FUNCTION( 45 (int), new_window, tag, (required (title,*)(width,*)(titlebar,*))) 46 { 47 return 0; 48 } 49 50 BOOST_PARAMETER_TEMPLATE_KEYWORD(deleter) 51 BOOST_PARAMETER_TEMPLATE_KEYWORD(copy_policy) 52 53 template <class T> struct Deallocate {}; 54 struct DeepCopy {}; 55 56 namespace parameter = boost::parameter; 57 58 struct Foo {}; 59 template <class T, class A0, class A1> 60 struct smart_ptr 61 { 62 smart_ptr(Foo*); 63 }; 64 } 65 using namespace test; 66 int x = '''); 67 68.. @test('compile') 69 70 71------------------------------------- 72 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 $ 77 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) 82 83.. _`BoostPro Computing`: http://www.boostpro.com 84 85.. _concepts: http://www.boost.org/more/generic_programming.html#concept 86 87------------------------------------- 88 89[Note: this tutorial does not cover all details of the library. Please see also the `reference documentation`__\ ] 90 91__ reference.html 92 93.. contents:: **Table of Contents** 94 :depth: 2 95 96.. role:: concept 97 :class: concept 98 99.. role:: vellipsis 100 :class: vellipsis 101 102.. section-numbering:: 103 104------------------------------------- 105 106============ 107 Motivation 108============ 109 110In C++, arguments_ are normally given meaning by their positions 111with respect to a parameter_ list: the first argument passed maps 112onto the first parameter in a function's definition, and so on. 113That protocol is fine when there is at most one parameter with a 114default value, but when there are even a few useful defaults, the 115positional interface becomes burdensome: 116 117* .. compound:: 118 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: 122 123 .. parsed-literal:: 124 125 window* new_window( 126 char const* name, 127 **int border_width = default_border_width,** 128 bool movable = true, 129 bool initially_visible = true 130 ); 131 132 const bool movability = false; 133 window* w = new_window("alert box", movability); 134 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: 139 140 .. parsed-literal:: 141 142 window* w = new_window( 143 "alert box", **default_border_width**, movability); 144 145* .. compound:: 146 147 It can become difficult for readers to understand the meaning of 148 arguments at the call site:: 149 150 window* w = new_window("alert", 1, true, false); 151 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. 155 156* The author of the call may not remember the order of the 157 arguments either, leading to hard-to-find bugs. 158 159.. @ignore(3) 160 161------------------------- 162Named Function Parameters 163------------------------- 164 165.. compound:: 166 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: 170 171 .. parsed-literal:: 172 173 window* w = new_window("alert box", **movable_=**\ false); // OK! 174 175.. @ignore() 176 177--------------------------- 178Deduced Function Parameters 179--------------------------- 180 181.. compound:: 182 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: 191 192 .. parsed-literal:: 193 194 window* w = new_window(movable_=false, **"alert box"**); // OK! 195 window* w = new_window(**"alert box"**, movable_=false); // OK! 196 197 Appropriately used, a deduced parameter interface can free the 198 user of the burden of even remembering the formal parameter 199 names. 200 201.. @ignore() 202 203-------------------------------- 204Class Template Parameter Support 205-------------------------------- 206 207.. compound:: 208 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: 214 215 .. parsed-literal:: 216 217 smart_ptr<**ownership<shared>**, **value_type<Client>** > p; 218 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: 224 225 .. parsed-literal:: 226 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; 231 232.. @ignore(2) 233 234========== 235 Tutorial 236========== 237 238This tutorial shows all the basics—how to build both named- and deduced-parameter 239interfaces to function templates and class templates—and several 240more advanced idioms as well. 241 242--------------------------- 243Parameter-Enabled Functions 244--------------------------- 245 246In this section we'll show how the Parameter library can be used to 247build an expressive interface to the `Boost Graph library`__\ 's 248|dfs|_ algorithm. [#old_interface]_ 249 250.. Revisit this 251 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. 260 261__ ../../../graph/index.html 262 263.. _dfs: ../../../graph/doc/depth_first_search.html 264 265.. |dfs| replace:: ``depth_first_search`` 266 267 268Headers And Namespaces 269====================== 270 271Most components of the Parameter library are declared in a 272header named for the component. For example, :: 273 274 #include <boost/parameter/keyword.hpp> 275 276will ensure ``boost::parameter::keyword`` is known to the 277compiler. There is also a combined header, 278``boost/parameter.hpp``, that includes most of the library's 279components. For the the rest of this tutorial, unless we say 280otherwise, you can use the rule above to figure out which header 281to ``#include`` to access any given component of the library. 282 283.. @example.append(''' 284 using boost::parameter::keyword; 285 ''') 286 287.. @test('compile') 288 289Also, the examples below will also be written as if the 290namespace alias :: 291 292 namespace parameter = boost::parameter; 293 294.. @ignore() 295 296has been declared: we'll write ``parameter::xxx`` instead of 297``boost::parameter::xxx``. 298 299The Abstract Interface to |dfs| 300=============================== 301 302The Graph library's |dfs| algorithm is a generic function accepting 303from one to four arguments by reference. If all arguments were 304required, its signature might be as follows:: 305 306 template < 307 class Graph, class DFSVisitor, class Index, class ColorMap 308 > 309 void depth_first_search( 310 , Graph const& graph 311 , DFSVisitor visitor 312 , typename graph_traits<g>::vertex_descriptor root_vertex 313 , IndexMap index_map 314 , ColorMap& color); 315 316.. @ignore() 317 318However, most of the parameters have a useful default value, as 319shown in the table below. 320 321.. _`parameter table`: 322.. _`default expressions`: 323 324.. table:: ``depth_first_search`` Parameters 325 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|_ | | 331 | | | | | 332 +----------------+----------+---------------------------------+----------------------------------+ 333 |``visitor`` | in |Model of |DFSVisitor|_ |``boost::dfs_visitor<>()`` | 334 +----------------+----------+---------------------------------+----------------------------------+ 335 |``root_vertex`` | in |``graph``'s vertex descriptor |``*vertices(graph).first`` | 336 | | |type. | | 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 +----------------+----------+---------------------------------+----------------------------------+ 349 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` 355 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 361 362Don't be intimidated by the information in the second and third 363columns above. For the purposes of this exercise, you don't need 364to understand them in detail. 365 366Defining the Keywords 367===================== 368 369The point of this exercise is to make it possible to call 370``depth_first_search`` with named arguments, leaving out any 371arguments for which the default is appropriate: 372 373.. parsed-literal:: 374 375 graphs::depth_first_search(g, **color_map_=my_color_map**); 376 377.. @ignore() 378 379To 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 383identified by a unique **keyword tag type**. 384 385.. Revisit this 386 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. 393 394We're going to define our interface in namespace ``graphs``. The 395library provides a convenient macro for defining keyword objects:: 396 397 #include <boost/parameter/name.hpp> 398 399 namespace graphs 400 { 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) 406 } 407 408.. @test('compile') 409 410The declaration of the ``graph`` keyword you see here is 411equivalent to:: 412 413 namespace graphs 414 { 415 namespace tag { struct graph; } // keyword tag type 416 417 namespace // unnamed 418 { 419 // A reference to the keyword object 420 boost::parameter::keyword<tag::graph>& _graph 421 = boost::parameter::keyword<tag::graph>::get(); 422 } 423 } 424 425.. @example.prepend('#include <boost/parameter/keyword.hpp>') 426.. @test('compile') 427 428It defines a *keyword tag type* named ``tag::graph`` and a *keyword 429object* reference named ``_graph``. 430 431This “fancy dance” involving an unnamed namespace and references 432is all done to avoid violating the One Definition Rule (ODR) 433[#odr]_ when the named parameter interface is used by function 434templates that are instantiated in multiple translation 435units (MSVC6.x users see `this note`__). 436 437__ `Compiler Can't See References In Unnamed Namespace`_ 438 439Writing the Function 440==================== 441 442Now that we have our keywords defined, the function template 443definition follows a simple pattern using the 444``BOOST_PARAMETER_FUNCTION`` macro:: 445 446 #include <boost/parameter/preprocessor.hpp> 447 448 namespace graphs 449 { 450 BOOST_PARAMETER_FUNCTION( 451 (void), // 1. parenthesized return type 452 depth_first_search, // 2. name of the function template 453 454 tag, // 3. namespace of tag types 455 456 (required (graph, *) ) // 4. one required parameter, and 457 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) ) 464 ) 465 ) 466 { 467 // ... body of function goes here... 468 // use graph, visitor, index_map, and color_map 469 } 470 } 471 472.. @example.prepend(''' 473 #include <boost/parameter/name.hpp> 474 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) 480 481 namespace boost { 482 483 template <class T = int> 484 struct dfs_visitor 485 {}; 486 487 int vertex_index = 0; 488 489 }''') 490 491.. @test('compile') 492 493The arguments to ``BOOST_PARAMETER_FUNCTION`` are: 494 4951. 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. 498 4992. The name of the resulting function template. 500 5013. The name of a namespace where we can find tag types whose names 502 match the function's parameter names. 503 5044. The function signature. 505 506Function Signatures 507=================== 508 509Function signatures are described as one or two adjacent 510parenthesized terms (a Boost.Preprocessor_ sequence_) describing 511the function's parameters in the order in which they'd be expected 512if passed positionally. Any required parameters must come first, 513but the ``(required … )`` clause can be omitted when all the 514parameters are optional. 515 516.. _Boost.Preprocessor: ../../../preprocessor/index.html 517 518Required Parameters 519------------------- 520 521.. compound:: 522 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 527 tuple: 528 529 .. parsed-literal:: 530 531 (required **(graph, \*)** ) 532 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 538 entirely. 539 540.. @example.prepend(''' 541 #include <boost/parameter.hpp> 542 543 BOOST_PARAMETER_NAME(graph) 544 545 BOOST_PARAMETER_FUNCTION((void), f, tag, 546 ''') 547 548.. @example.append(') {}') 549.. @test('compile') 550 551Optional Parameters 552------------------- 553 554.. compound:: 555 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: 560 561 .. parsed-literal:: 562 563 (optional **\ 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) )** 569 ) 570 571.. @example.prepend(''' 572 #include <boost/parameter.hpp> 573 574 namespace boost 575 { 576 int vertex_index = 0; 577 578 template <class T = int> 579 struct dfs_visitor 580 {}; 581 } 582 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) 588 589 BOOST_PARAMETER_FUNCTION((void), f, tag, 590 (required (graph, *)) 591 ''') 592 593.. @example.append(') {}') 594.. @test('compile') 595 596Handling “Out” Parameters 597------------------------- 598 599.. compound:: 600 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(…)``: 609 610 .. parsed-literal:: 611 612 (optional 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) ) 618 ) 619 620.. @example.prepend(''' 621 #include <boost/parameter.hpp> 622 623 namespace boost 624 { 625 int vertex_index = 0; 626 627 template <class T = int> 628 struct dfs_visitor 629 {}; 630 } 631 632 BOOST_PARAMETER_NAME(graph) 633 634 BOOST_PARAMETER_NAME(visitor) 635 BOOST_PARAMETER_NAME(root_vertex) 636 BOOST_PARAMETER_NAME(index_map) 637 BOOST_PARAMETER_NAME(color_map) 638 639 BOOST_PARAMETER_FUNCTION((void), f, tag, 640 (required (graph, *)) 641 ''') 642 643.. @example.append(') {}') 644.. @test('compile') 645 646If ``color_map`` were strictly going to be modified but not examined, 647we could have written ``out(color_map)``. There is no functional 648difference between ``out`` and ``in_out``; the library provides 649both so you can make your interfaces more self-documenting. 650 651Positional Arguments 652-------------------- 653 654When arguments are passed positionally (without the use of 655keywords), they will be mapped onto parameters in the order the 656parameters are given in the signature, so for example in this 657call :: 658 659 graphs::depth_first_search(x, y); 660 661.. @ignore() 662 663``x`` will always be interpreted as a graph and ``y`` will always 664be interpreted as a visitor. 665 666.. _sequence: http://boost-consulting.com/mplbook/preprocessor.html#sequences 667 668Default Expression Evaluation 669----------------------------- 670 671.. compound:: 672 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``. 676 677 .. parsed-literal:: 678 679 (required (**graph**, \*) ) 680 (optional 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) ) 686 ) 687 688 .. @ignore() 689 690 A default expression is evaluated in the context of all preceding 691 parameters, so you can use any of their values by name. 692 693.. compound:: 694 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: 699 700 .. parsed-literal:: 701 702 #include <boost/graph/depth_first_search.hpp> // for dfs_visitor 703 704 BOOST_PARAMETER_FUNCTION( 705 (void), depth_first_search, tag 706 *…signature goes here…* 707 ) 708 { 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; 714 } 715 716 int main() 717 { 718 depth_first_search(1, 2, 3, 4, 5); 719 720 depth_first_search( 721 "1", '2', _color_map = '5', 722 _index_map = "4", _root_vertex = "3"); 723 } 724 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. 729 730.. @example.prepend(''' 731 #include <boost/parameter.hpp> 732 #include <iostream> 733 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)''') 739 740.. @example.replace_emphasis(''' 741 , (required 742 (graph, *) 743 (visitor, *) 744 (root_vertex, *) 745 (index_map, *) 746 (color_map, *) 747 ) 748 ''') 749.. @test('compile') 750 751Signature Matching and Overloading 752---------------------------------- 753 754In fact, the function signature is so general that any call to 755``depth_first_search`` with fewer than five arguments will match 756our function, provided we pass *something* for the required 757``graph`` parameter. That might not seem to be a problem at first; 758after all, if the arguments don't match the requirements imposed by 759the implementation of ``depth_first_search``, a compilation error 760will occur later, when its body is instantiated. 761 762There are at least three problems with very general function 763signatures. 764 7651. 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. 770 7712. 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]_ 778 7793. 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? 785 786__ http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#225 787 788It's usually a good idea to prevent functions from being considered 789for overload resolution when the passed argument types aren't 790appropriate. The library already does this when the required 791``graph`` parameter is not supplied, but we're not likely to see a 792depth first search that doesn't take a graph to operate on. 793Suppose, instead, that we found a different depth first search 794algorithm that could work on graphs that don't model 795|IncidenceGraph|_? If we just added a simple overload, 796it would be ambiguous:: 797 798 // new overload 799 BOOST_PARAMETER_FUNCTION( 800 (void), depth_first_search, (tag), (required (graph,*))( … )) 801 { 802 // new algorithm implementation 803 } 804 805 … 806 807 // ambiguous! 808 depth_first_search(boost::adjacency_list<>(), 2, "hello"); 809 810.. @ignore() 811 812Adding Type Requirements 813........................ 814 815We really don't want the compiler to consider the original version 816of ``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 819should just invoke our new overload. To take the original 820``depth_first_search`` overload out of contention, we need to tell 821the library about this requirement by replacing the ``*`` element 822of the signature with the required type, in parentheses: 823 824__ `parameter table`_ 825 826.. parsed-literal:: 827 828 (root_vertex, 829 **(typename boost::graph_traits<graph_type>::vertex_descriptor)**, 830 \*vertices(graph).first) 831 832.. @ignore() 833 834Now the original ``depth_first_search`` will only be called when 835the ``root_vertex`` argument can be converted to the graph's vertex 836descriptor type, and our example that *was* ambiguous will smoothly 837call the new overload. 838 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*\ 842 ``_type``. 843 844 845Predicate Requirements 846...................... 847 848The requirements on other arguments are a bit more interesting than 849those on ``root_vertex``; they can't be described in terms of simple 850type matching. Instead, they must be described in terms of `MPL 851Metafunctions`__. There's no space to give a complete description 852of metafunctions or of graph library details here, but we'll show 853you the complete signature with maximal checking, just to give you 854a feel for how it's done. Each predicate metafunction is enclosed 855in parentheses *and preceded by an asterix*, as follows: 856 857.. parsed-literal:: 858 859 BOOST_PARAMETER_FUNCTION( 860 (void), depth_first_search, graphs 861 862 , (required 863 (graph 864 , **\ \*(boost::mpl::and_< 865 boost::is_convertible< 866 boost::graph_traits<_>::traversal_category 867 , boost::incidence_graph_tag 868 > 869 , boost::is_convertible< 870 boost::graph_traits<_>::traversal_category 871 , boost::vertex_list_graph_tag 872 > 873 >)** )) 874 875 (optional 876 (visitor, \*, boost::dfs_visitor<>()) // not checkable 877 878 (root_vertex 879 , (typename boost::graph_traits<graphs::graph::_>::vertex_descriptor) 880 , \*vertices(graph).first) 881 882 (index_map 883 , **\ \*(boost::mpl::and_< 884 boost::is_integral< 885 boost::property_traits<_>::value_type 886 > 887 , boost::is_same< 888 typename boost::graph_traits<graphs::graph::_>::vertex_descriptor 889 , boost::property_traits<_>::key_type 890 > 891 >)** 892 , get(boost::vertex_index,graph)) 893 894 (in_out(color_map) 895 , **\ \*(boost::is_same< 896 typename boost::graph_traits<graphs::graph::_>::vertex_descriptor 897 , boost::property_traits<_>::key_type 898 >)** 899 , default_color_map(num_vertices(graph), index_map) ) 900 ) 901 ) 902 903.. @example.prepend(''' 904 #include <boost/parameter.hpp> 905 906 BOOST_PARAMETER_NAME((_graph, graphs) graph) 907 BOOST_PARAMETER_NAME((_visitor, graphs) visitor) 908 BOOST_PARAMETER_NAME((_root_vertex, graphs) root_vertex) 909 BOOST_PARAMETER_NAME((_index_map, graphs) index_map) 910 BOOST_PARAMETER_NAME((_color_map, graphs) color_map) 911 912 using boost::mpl::_; 913 914 namespace boost 915 { 916 struct incidence_graph_tag {}; 917 struct vertex_list_graph_tag {}; 918 919 int vertex_index = 0; 920 921 template <class T> 922 struct graph_traits 923 { 924 typedef int traversal_category; 925 typedef int vertex_descriptor; 926 }; 927 928 template <class T> 929 struct property_traits 930 { 931 typedef int value_type; 932 typedef int key_type; 933 }; 934 935 template <class T = int> 936 struct dfs_visitor 937 {}; 938 }''') 939 940.. @example.append(''' 941 {}''') 942 943.. @test('compile') 944 945__ ../../../mpl/doc/refmanual/metafunction.html 946 947We acknowledge that this signature is pretty hairy looking. 948Fortunately, it usually isn't necessary to so completely encode the 949type requirements on arguments to generic functions. However, it 950is usally worth the effort to do so: your code will be more 951self-documenting and will often provide a better user experience. 952You'll also have an easier transition to an upcoming C++ standard 953with `language support for concepts`__. 954 955__ `ConceptC++`_ 956 957Deduced Parameters 958------------------ 959 960To illustrate deduced parameter support we'll have to leave behind 961our example from the Graph library. Instead, consider the example 962of the |def|_ function from Boost.Python_. Its signature is 963roughly as follows:: 964 965 template < 966 class Function, Class KeywordExpression, class CallPolicies 967 > 968 void def( 969 // Required parameters 970 char const* name, Function func 971 972 // Optional, deduced parameters 973 , char const* docstring = "" 974 , KeywordExpression keywords = no_keywords() 975 , CallPolicies policies = default_call_policies() 976 ); 977 978.. @ignore() 979 980Try not to be too distracted by the use of the term “keywords” in 981this example: although it means something analogous in Boost.Python 982to what it means in the Parameter library, for the purposes of this 983exercise you can think of it as being completely different. 984 985When calling ``def``, only two arguments are required. The 986association between any additional arguments and their parameters 987can be determined by the types of the arguments actually passed, so 988the caller is neither required to remember argument positions or 989explicitly specify parameter names for those arguments. To 990generate this interface using ``BOOST_PARAMETER_FUNCTION``, we need 991only enclose the deduced parameters in a ``(deduced …)`` clause, as 992follows: 993 994.. parsed-literal:: 995 996 namespace mpl = boost::mpl; 997 998 BOOST_PARAMETER_FUNCTION( 999 (void), def, tag, 1000 1001 (required (name,(char const\*)) (func,\*) ) // nondeduced 1002 1003 **(deduced** 1004 (optional 1005 (docstring, (char const\*), "") 1006 1007 (keywords 1008 , \*(is_keyword_expression<mpl::_>) // see [#is_keyword_expression]_ 1009 , no_keywords()) 1010 1011 (policies 1012 , \*(mpl::not_< 1013 mpl::or_< 1014 boost::is_convertible<mpl::_, char const\*> 1015 , is_keyword_expression<mpl::_> // see [#is_keyword_expression]_ 1016 > 1017 >) 1018 , default_call_policies() 1019 ) 1020 ) 1021 **)** 1022 ) 1023 { 1024 *…* 1025 } 1026 1027.. @example.replace_emphasis('') 1028 1029.. @example.prepend(''' 1030 #include <boost/parameter.hpp> 1031 1032 BOOST_PARAMETER_NAME(name) 1033 BOOST_PARAMETER_NAME(func) 1034 BOOST_PARAMETER_NAME(docstring) 1035 BOOST_PARAMETER_NAME(keywords) 1036 BOOST_PARAMETER_NAME(policies) 1037 1038 struct default_call_policies 1039 {}; 1040 1041 struct no_keywords 1042 {}; 1043 1044 struct keywords 1045 {}; 1046 1047 template <class T> 1048 struct is_keyword_expression 1049 : boost::mpl::false_ 1050 {}; 1051 1052 template <> 1053 struct is_keyword_expression<keywords> 1054 : boost::mpl::true_ 1055 {}; 1056 1057 default_call_policies some_policies; 1058 1059 void f() 1060 {} 1061 1062 ''') 1063 1064.. Admonition:: Syntax Note 1065 1066 A ``(deduced …)`` clause always contains a ``(required …)`` 1067 and/or an ``(optional …)`` subclause, and must follow any 1068 ``(required …)`` or ``(optional …)`` clauses indicating 1069 nondeduced parameters at the outer level. 1070 1071With the declaration above, the following two calls are equivalent: 1072 1073.. parsed-literal:: 1074 1075 def("f", &f, **some_policies**, **"Documentation for f"**); 1076 def("f", &f, **"Documentation for f"**, **some_policies**); 1077 1078.. @example.prepend(''' 1079 int main() 1080 {''') 1081 1082If the user wants to pass a ``policies`` argument that was also, 1083for some reason, convertible to ``char const*``, she can always 1084specify the parameter name explicitly, as follows: 1085 1086.. parsed-literal:: 1087 1088 def( 1089 "f", &f 1090 , **_policies = some_policies**, "Documentation for f"); 1091 1092.. @example.append('}') 1093.. @test('compile', howmany='all') 1094 1095.. _Boost.Python: ../../../python/doc/index.html 1096.. |def| replace:: ``def`` 1097.. _def: ../../../python/doc/v2/def.html 1098 1099---------------------------------- 1100Parameter-Enabled Member Functions 1101---------------------------------- 1102 1103 1104The ``BOOST_PARAMETER_MEMBER_FUNCTION`` and 1105``BOOST_PARAMETER_CONST_MEMBER_FUNCTION`` macros accept exactly the 1106same arguments as ``BOOST_PARAMETER_FUNCTION``, but are designed to 1107be used within the body of a class:: 1108 1109 BOOST_PARAMETER_NAME(arg1) 1110 BOOST_PARAMETER_NAME(arg2) 1111 1112 struct callable2 1113 { 1114 BOOST_PARAMETER_CONST_MEMBER_FUNCTION( 1115 (void), call, tag, (required (arg1,(int))(arg2,(int)))) 1116 { 1117 std::cout << arg1 << ", " << arg2 << std::endl; 1118 } 1119 }; 1120 1121.. @example.prepend(''' 1122 #include <boost/parameter.hpp> 1123 #include <iostream> 1124 using namespace boost::parameter; 1125 ''') 1126 1127.. @test('compile') 1128 1129These macros don't directly allow a function's interface to be 1130separated from its implementation, but you can always forward 1131arguments on to a separate implementation function:: 1132 1133 struct callable2 1134 { 1135 BOOST_PARAMETER_CONST_MEMBER_FUNCTION( 1136 (void), call, tag, (required (arg1,(int))(arg2,(int)))) 1137 { 1138 call_impl(arg1,arg2); 1139 } 1140 private: 1141 void call_impl(int, int); // implemented elsewhere. 1142 }; 1143 1144.. @example.prepend(''' 1145 #include <boost/parameter.hpp> 1146 1147 BOOST_PARAMETER_NAME(arg1) 1148 BOOST_PARAMETER_NAME(arg2) 1149 using namespace boost::parameter; 1150 ''') 1151 1152.. @test('compile') 1153 1154Static Member Functions 1155======================= 1156 1157To expose a static member function, simply insert the keyword 1158“``static``” before the function name: 1159 1160.. parsed-literal:: 1161 1162 BOOST_PARAMETER_NAME(arg1) 1163 1164 struct somebody 1165 { 1166 BOOST_PARAMETER_MEMBER_FUNCTION( 1167 (void), **static** f, tag, (optional (arg1,(int),0))) 1168 { 1169 std::cout << arg1 << std::endl; 1170 } 1171 }; 1172 1173.. @example.prepend(''' 1174 #include <boost/parameter.hpp> 1175 #include <iostream> 1176 using namespace boost::parameter; 1177 ''') 1178 1179.. @test('compile') 1180 1181 1182------------------------------ 1183Parameter-Enabled Constructors 1184------------------------------ 1185 1186The lack of a “delegating constructor” 1187feature in C++ 1188(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf) 1189limits somewhat the quality of interface this library can provide 1190for defining parameter-enabled constructors. The usual workaround 1191for a lack of constructor delegation applies: one must factor the 1192common logic into a base class. 1193 1194Let's build a parameter-enabled constructor that simply prints its 1195arguments. The first step is to write a base class whose 1196constructor accepts a single argument known as an |ArgumentPack|_: 1197a bundle of references to the actual arguments, tagged with their 1198keywords. The values of the actual arguments are extracted from 1199the |ArgumentPack| by *indexing* it with keyword objects:: 1200 1201 BOOST_PARAMETER_NAME(name) 1202 BOOST_PARAMETER_NAME(index) 1203 1204 struct myclass_impl 1205 { 1206 template <class ArgumentPack> 1207 myclass_impl(ArgumentPack const& args) 1208 { 1209 std::cout << "name = " << args[_name] 1210 << "; index = " << args[_index | 42] 1211 << std::endl; 1212 } 1213 }; 1214 1215.. @example.prepend(''' 1216 #include <boost/parameter.hpp> 1217 #include <iostream>''') 1218 1219Note that the bitwise or (“\ ``|``\ ”) operator has a special 1220meaning when applied to keyword objects that are passed to an 1221|ArgumentPack|\ 's indexing operator: it is used to indicate a 1222default value. In this case if there is no ``index`` parameter in 1223the |ArgumentPack|, ``42`` will be used instead. 1224 1225Now we are ready to write the parameter-enabled constructor 1226interface:: 1227 1228 struct myclass : myclass_impl 1229 { 1230 BOOST_PARAMETER_CONSTRUCTOR( 1231 myclass, (myclass_impl), tag 1232 , (required (name,*)) (optional (index,*))) // no semicolon 1233 }; 1234 1235Since we have supplied a default value for ``index`` but not for 1236``name``, only ``name`` is required. We can exercise our new 1237interface as follows:: 1238 1239 myclass x("bob", 3); // positional 1240 myclass y(_index = 12, _name = "sally"); // named 1241 myclass z("june"); // positional/defaulted 1242 1243.. @example.wrap('int main() {', '}') 1244.. @test('run', howmany='all') 1245 1246For more on |ArgumentPack| manipulation, see the `Advanced Topics`_ 1247section. 1248 1249--------------------------------- 1250Parameter-Enabled Class Templates 1251--------------------------------- 1252 1253In this section we'll use Boost.Parameter to build Boost.Python_\ 1254's `class_`_ template, whose “signature” is: 1255 1256.. parsed-literal:: 1257 1258 template class< 1259 ValueType, BaseList = bases<> 1260 , HeldType = ValueType, Copyable = void 1261 > 1262 class class\_; 1263 1264.. @ignore() 1265 1266Only the first argument, ``ValueType``, is required. 1267 1268.. _class_: http://www.boost.org/libs/python/doc/v2/class.html#class_-spec 1269 1270Named Template Parameters 1271========================= 1272 1273First, we'll build an interface that allows users to pass arguments 1274positionally or by name: 1275 1276.. parsed-literal:: 1277 1278 struct B { virtual ~B() = 0; }; 1279 struct D : B { ~D(); }; 1280 1281 class_< 1282 **class_type<B>**, **copyable<boost::noncopyable>** 1283 > …; 1284 1285 class_< 1286 **D**, **held_type<std::auto_ptr<D> >**, **base_list<bases<B> >** 1287 > …; 1288 1289.. @ignore() 1290 1291Template Keywords 1292----------------- 1293 1294The first step is to define keywords for each template parameter:: 1295 1296 namespace boost { namespace python { 1297 1298 BOOST_PARAMETER_TEMPLATE_KEYWORD(class_type) 1299 BOOST_PARAMETER_TEMPLATE_KEYWORD(base_list) 1300 BOOST_PARAMETER_TEMPLATE_KEYWORD(held_type) 1301 BOOST_PARAMETER_TEMPLATE_KEYWORD(copyable) 1302 1303 }} 1304 1305.. @example.prepend('#include <boost/parameter.hpp>') 1306.. @test('compile') 1307 1308The declaration of the ``class_type`` keyword you see here is 1309equivalent to:: 1310 1311 namespace boost { namespace python { 1312 1313 namespace tag { struct class_type; } // keyword tag type 1314 template <class T> 1315 struct class_type 1316 : parameter::template_keyword<tag::class_type,T> 1317 {}; 1318 1319 }} 1320 1321.. @example.prepend('#include <boost/parameter.hpp>') 1322.. @test('compile') 1323 1324It defines a keyword tag type named ``tag::class_type`` and a 1325*parameter passing template* named ``class_type``. 1326 1327Class Template Skeleton 1328----------------------- 1329 1330The next step is to define the skeleton of our class template, 1331which has three optional parameters. Because the user may pass 1332arguments in any order, we don't know the actual identities of 1333these parameters, so it would be premature to use descriptive names 1334or write out the actual default values for any of them. Instead, 1335we'll give them generic names and use the special type 1336``boost::parameter::void_`` as a default: 1337 1338.. parsed-literal:: 1339 1340 namespace boost { namespace python { 1341 1342 template < 1343 class A0 1344 , class A1 = parameter::void\_ 1345 , class A2 = parameter::void\_ 1346 , class A3 = parameter::void\_ 1347 > 1348 struct class\_ 1349 { 1350 *…* 1351 }; 1352 1353 }} 1354 1355.. @example.prepend('#include <boost/parameter.hpp>') 1356.. @example.replace_emphasis('') 1357.. @test('compile') 1358 1359Class Template Signatures 1360------------------------- 1361 1362Next, we need to build a type, known as a |ParameterSpec|_, 1363describing the “signature” of ``boost::python::class_``. A 1364|ParameterSpec|_ enumerates the required and optional parameters in 1365their positional order, along with any type requirements (note that 1366it does *not* specify defaults -- those will be dealt with 1367separately):: 1368 1369 namespace boost { namespace python { 1370 1371 using boost::mpl::_; 1372 1373 typedef parameter::parameters< 1374 required<tag::class_type, boost::is_class<_> > 1375 , parameter::optional<tag::base_list, mpl::is_sequence<_> > 1376 , parameter::optional<tag::held_type> 1377 , parameter::optional<tag::copyable> 1378 > class_signature; 1379 1380 }} 1381 1382.. @example.prepend(''' 1383 #include <boost/parameter.hpp> 1384 #include <boost/mpl/is_sequence.hpp> 1385 #include <boost/noncopyable.hpp> 1386 #include <boost/type_traits/is_class.hpp> 1387 #include <memory> 1388 1389 using namespace boost::parameter; 1390 1391 namespace boost { namespace python { 1392 1393 BOOST_PARAMETER_TEMPLATE_KEYWORD(class_type) 1394 BOOST_PARAMETER_TEMPLATE_KEYWORD(base_list) 1395 BOOST_PARAMETER_TEMPLATE_KEYWORD(held_type) 1396 BOOST_PARAMETER_TEMPLATE_KEYWORD(copyable) 1397 1398 template <class B = int> 1399 struct bases 1400 {}; 1401 1402 }}''') 1403 1404.. |ParameterSpec| replace:: :concept:`ParameterSpec` 1405 1406.. _ParameterSpec: reference.html#parameterspec 1407 1408.. _binding_intro: 1409 1410Argument Packs and Parameter Extraction 1411--------------------------------------- 1412 1413Next, within the body of ``class_`` , we use the |ParameterSpec|\ 's 1414nested ``::bind< … >`` template to bundle the actual arguments into an 1415|ArgumentPack|_ type, and then use the library's ``value_type< … >`` 1416metafunction to extract “logical parameters”. ``value_type< … >`` is 1417a lot like ``binding< … >``, but no reference is added to the actual 1418argument type. Note that defaults are specified by passing it an 1419optional third argument:: 1420 1421 namespace boost { namespace python { 1422 1423 template < 1424 class A0 1425 , class A1 = parameter::void_ 1426 , class A2 = parameter::void_ 1427 , class A3 = parameter::void_ 1428 > 1429 struct class_ 1430 { 1431 // Create ArgumentPack 1432 typedef typename 1433 class_signature::bind<A0,A1,A2,A3>::type 1434 args; 1435 1436 // Extract first logical parameter. 1437 typedef typename parameter::value_type< 1438 args, tag::class_type>::type class_type; 1439 1440 typedef typename parameter::value_type< 1441 args, tag::base_list, bases<> >::type base_list; 1442 1443 typedef typename parameter::value_type< 1444 args, tag::held_type, class_type>::type held_type; 1445 1446 typedef typename parameter::value_type< 1447 args, tag::copyable, void>::type copyable; 1448 }; 1449 1450 }} 1451 1452.. |ArgumentPack| replace:: :concept:`ArgumentPack` 1453.. _ArgumentPack: reference.html#argumentpack 1454 1455Exercising the Code So Far 1456========================== 1457 1458.. compound:: 1459 1460 Revisiting our original examples, :: 1461 1462 typedef boost::python::class_< 1463 class_type<B>, copyable<boost::noncopyable> 1464 > c1; 1465 1466 typedef boost::python::class_< 1467 D, held_type<std::auto_ptr<D> >, base_list<bases<B> > 1468 > c2; 1469 1470 .. @example.prepend(''' 1471 using boost::python::class_type; 1472 using boost::python::copyable; 1473 using boost::python::held_type; 1474 using boost::python::base_list; 1475 using boost::python::bases; 1476 1477 struct B {}; 1478 struct D {};''') 1479 1480 we can now examine the intended parameters:: 1481 1482 BOOST_MPL_ASSERT((boost::is_same<c1::class_type, B>)); 1483 BOOST_MPL_ASSERT((boost::is_same<c1::base_list, bases<> >)); 1484 BOOST_MPL_ASSERT((boost::is_same<c1::held_type, B>)); 1485 BOOST_MPL_ASSERT(( 1486 boost::is_same<c1::copyable, boost::noncopyable> 1487 )); 1488 1489 BOOST_MPL_ASSERT((boost::is_same<c2::class_type, D>)); 1490 BOOST_MPL_ASSERT((boost::is_same<c2::base_list, bases<B> >)); 1491 BOOST_MPL_ASSERT(( 1492 boost::is_same<c2::held_type, std::auto_ptr<D> > 1493 )); 1494 BOOST_MPL_ASSERT((boost::is_same<c2::copyable, void>)); 1495 1496.. @test('compile', howmany='all') 1497 1498Deduced Template Parameters 1499=========================== 1500 1501To apply a deduced parameter interface here, we need only make the 1502type requirements a bit tighter so the ``held_type`` and 1503``copyable`` parameters can be crisply distinguished from the 1504others. Boost.Python_ does this by requiring that ``base_list`` be 1505a specialization of its ``bases< … >`` template (as opposed to 1506being any old MPL sequence) and by requiring that ``copyable``, if 1507explicitly supplied, be ``boost::noncopyable``. One easy way of 1508identifying specializations of ``bases< … >`` is to derive them all 1509from the same class, as an implementation detail: 1510 1511.. parsed-literal:: 1512 1513 namespace boost { namespace python { 1514 1515 namespace detail { struct bases_base {}; } 1516 1517 template <class A0 = void, class A1 = void, class A2 = void *…* > 1518 struct bases **: detail::bases_base** 1519 {}; 1520 1521 }} 1522 1523.. @example.replace_emphasis('') 1524.. @example.prepend(''' 1525 #include <boost/parameter.hpp> 1526 #include <boost/mpl/is_sequence.hpp> 1527 #include <boost/noncopyable.hpp> 1528 #include <memory> 1529 1530 using namespace boost::parameter; 1531 using boost::mpl::_; 1532 1533 namespace boost { namespace python { 1534 1535 BOOST_PARAMETER_TEMPLATE_KEYWORD(class_type) 1536 BOOST_PARAMETER_TEMPLATE_KEYWORD(base_list) 1537 BOOST_PARAMETER_TEMPLATE_KEYWORD(held_type) 1538 BOOST_PARAMETER_TEMPLATE_KEYWORD(copyable) 1539 1540 }}''') 1541 1542Now we can rewrite our signature to make all three optional 1543parameters deducible:: 1544 1545 typedef parameter::parameters< 1546 required<tag::class_type, is_class<_> > 1547 1548 , parameter::optional< 1549 deduced<tag::base_list> 1550 , is_base_and_derived<detail::bases_base,_> 1551 > 1552 1553 , parameter::optional< 1554 deduced<tag::held_type> 1555 , mpl::not_< 1556 mpl::or_< 1557 is_base_and_derived<detail::bases_base,_> 1558 , is_same<noncopyable,_> 1559 > 1560 > 1561 > 1562 1563 , parameter::optional<deduced<tag::copyable>, is_same<noncopyable,_> > 1564 1565 > class_signature; 1566 1567.. @example.prepend(''' 1568 #include <boost/type_traits/is_class.hpp> 1569 namespace boost { namespace python {''') 1570 1571.. @example.append(''' 1572 template < 1573 class A0 1574 , class A1 = parameter::void_ 1575 , class A2 = parameter::void_ 1576 , class A3 = parameter::void_ 1577 > 1578 struct class_ 1579 { 1580 // Create ArgumentPack 1581 typedef typename 1582 class_signature::bind<A0,A1,A2,A3>::type 1583 args; 1584 1585 // Extract first logical parameter. 1586 typedef typename parameter::value_type< 1587 args, tag::class_type>::type class_type; 1588 1589 typedef typename parameter::value_type< 1590 args, tag::base_list, bases<> >::type base_list; 1591 1592 typedef typename parameter::value_type< 1593 args, tag::held_type, class_type>::type held_type; 1594 1595 typedef typename parameter::value_type< 1596 args, tag::copyable, void>::type copyable; 1597 }; 1598 1599 }}''') 1600 1601It may seem like we've added a great deal of complexity, but the 1602benefits to our users are greater. Our original examples can now 1603be written without explicit parameter names: 1604 1605.. parsed-literal:: 1606 1607 typedef boost::python::class_<**B**, **boost::noncopyable**> c1; 1608 1609 typedef boost::python::class_<**D**, **std::auto_ptr<D>**, **bases<B>** > c2; 1610 1611.. @example.prepend(''' 1612 struct B {}; 1613 struct D {}; 1614 1615 using boost::python::bases;''') 1616 1617.. @example.append(''' 1618 BOOST_MPL_ASSERT((boost::is_same<c1::class_type, B>)); 1619 BOOST_MPL_ASSERT((boost::is_same<c1::base_list, bases<> >)); 1620 BOOST_MPL_ASSERT((boost::is_same<c1::held_type, B>)); 1621 BOOST_MPL_ASSERT(( 1622 boost::is_same<c1::copyable, boost::noncopyable> 1623 )); 1624 1625 BOOST_MPL_ASSERT((boost::is_same<c2::class_type, D>)); 1626 BOOST_MPL_ASSERT((boost::is_same<c2::base_list, bases<B> >)); 1627 BOOST_MPL_ASSERT(( 1628 boost::is_same<c2::held_type, std::auto_ptr<D> > 1629 )); 1630 BOOST_MPL_ASSERT((boost::is_same<c2::copyable, void>));''') 1631 1632.. @test('compile', howmany='all') 1633 1634=============== 1635Advanced Topics 1636=============== 1637 1638At this point, you should have a good grasp of the basics. In this 1639section we'll cover some more esoteric uses of the library. 1640 1641------------------------- 1642Fine-Grained Name Control 1643------------------------- 1644 1645If you don't like the leading-underscore naming convention used 1646to refer to keyword objects, or you need the name ``tag`` for 1647something other than the keyword type namespace, there's another 1648way to use ``BOOST_PARAMETER_NAME``: 1649 1650.. parsed-literal:: 1651 1652 BOOST_PARAMETER_NAME(\ **(**\ *object-name*\ **,** *tag-namespace*\ **)** *parameter-name*\ ) 1653 1654.. @ignore() 1655 1656Here is a usage example: 1657 1658.. parsed-literal:: 1659 1660 BOOST_PARAMETER_NAME((**pass_foo**, **keywords**) **foo**) 1661 1662 BOOST_PARAMETER_FUNCTION( 1663 (int), f, 1664 **keywords**, (required (**foo**, \*))) 1665 { 1666 return **foo** + 1; 1667 } 1668 1669 int x = f(**pass_foo** = 41); 1670 1671.. @example.prepend('#include <boost/parameter.hpp>') 1672.. @example.append(''' 1673 int main() 1674 {}''') 1675.. @test('run') 1676 1677Before you use this more verbose form, however, please read the 1678section on `best practices for keyword object naming`__. 1679 1680__ `Keyword Naming`_ 1681 1682----------------------- 1683More |ArgumentPack|\ s 1684----------------------- 1685 1686We've already seen |ArgumentPack|\ s when we looked at 1687`parameter-enabled constructors`_ and `class templates`__. As you 1688might have guessed, |ArgumentPack|\ s actually lie at the heart of 1689everything this library does; in this section we'll examine ways to 1690build and manipulate them more effectively. 1691 1692__ binding_intro_ 1693 1694Building |ArgumentPack|\ s 1695========================== 1696 1697The simplest |ArgumentPack| is the result of assigning into a 1698keyword object:: 1699 1700 BOOST_PARAMETER_NAME(index) 1701 1702 template <class ArgumentPack> 1703 int print_index(ArgumentPack const& args) 1704 { 1705 std::cout << "index = " << args[_index] << std::endl; 1706 return 0; 1707 } 1708 1709 int x = print_index(_index = 3); // prints "index = 3" 1710 1711.. @example.prepend(''' 1712 #include <boost/parameter.hpp> 1713 #include <iostream>''') 1714 1715Also, |ArgumentPack|\ s can be composed using the comma operator. 1716The extra parentheses below are used to prevent the compiler from 1717seeing two separate arguments to ``print_name_and_index``:: 1718 1719 BOOST_PARAMETER_NAME(name) 1720 1721 template <class ArgumentPack> 1722 int print_name_and_index(ArgumentPack const& args) 1723 { 1724 std::cout << "name = " << args[_name] << "; "; 1725 return print_index(args); 1726 } 1727 1728 int y = print_name_and_index((_index = 3, _name = "jones")); 1729 1730To build an |ArgumentPack| with positional arguments, we can use a 1731|ParameterSpec|_. As introduced described in the section on `Class 1732Template Signatures`_, a |ParameterSpec| describes the positional 1733order of parameters and any associated type requirements. Just as 1734we can build an |ArgumentPack| *type* with its nested ``::bind< … 1735>`` template, we can build an |ArgumentPack| *object* by invoking 1736its function call operator: 1737 1738.. parsed-literal:: 1739 1740 parameter::parameters< 1741 required<tag::\ name, is_convertible<_,char const*> > 1742 , optional<tag::\ index, is_convertible<_,int> > 1743 > spec; 1744 1745 char const sam[] = "sam"; 1746 int twelve = 12; 1747 1748 int z0 = print_name_and_index( **spec(**\ sam, twelve\ **)** ); 1749 1750 int z1 = print_name_and_index( 1751 **spec(**\ _index=12, _name="sam"\ **)** 1752 ); 1753 1754.. @example.prepend(''' 1755 namespace parameter = boost::parameter; 1756 using parameter::required; 1757 using parameter::optional; 1758 using boost::is_convertible; 1759 using boost::mpl::_;''') 1760 1761.. @example.append(''' 1762 int main() 1763 {}''') 1764 1765.. @test('run', howmany='all') 1766 1767Note that because of the `forwarding problem`_, ``parameter::parameters::operator()`` 1768can't accept non-const rvalues. 1769 1770.. _`forwarding problem`: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm 1771 1772Extracting Parameter Types 1773========================== 1774 1775If we want to know the types of the arguments passed to 1776``print_name_and_index``, we have a couple of options. The 1777simplest and least error-prone approach is to forward them to a 1778function template and allow *it* to do type deduction:: 1779 1780 BOOST_PARAMETER_NAME(name) 1781 BOOST_PARAMETER_NAME(index) 1782 1783 template <class Name, class Index> 1784 int deduce_arg_types_impl(Name& name, Index& index) 1785 { 1786 Name& n2 = name; // we know the types 1787 Index& i2 = index; 1788 return index; 1789 } 1790 1791 template <class ArgumentPack> 1792 int deduce_arg_types(ArgumentPack const& args) 1793 { 1794 return deduce_arg_types_impl(args[_name], args[_index|42]); 1795 } 1796 1797.. @example.prepend(''' 1798 #include <boost/parameter.hpp> 1799 #include <cassert>''') 1800 1801.. @example.append(''' 1802 int a1 = deduce_arg_types((_name = "foo")); 1803 int a2 = deduce_arg_types((_name = "foo", _index = 3)); 1804 1805 int main() 1806 { 1807 assert(a1 == 42); 1808 assert(a2 == 3); 1809 }''') 1810 1811.. @test('run') 1812 1813Occasionally one needs to deduce argument types without an extra 1814layer of function call. For example, suppose we wanted to return 1815twice the value of the ``index`` parameter? In that 1816case we can use the ``value_type< … >`` metafunction introduced 1817`earlier`__:: 1818 1819 BOOST_PARAMETER_NAME(index) 1820 1821 template <class ArgumentPack> 1822 typename parameter::value_type<ArgumentPack, tag::index, int>::type 1823 twice_index(ArgumentPack const& args) 1824 { 1825 return 2 * args[_index|42]; 1826 } 1827 1828 int six = twice_index(_index = 3); 1829 1830.. @example.prepend(''' 1831 #include <boost/parameter.hpp> 1832 #include <boost/type_traits/remove_reference.hpp> 1833 #include <cassert> 1834 1835 namespace parameter = boost::parameter; 1836 ''') 1837 1838.. @example.append(''' 1839 int main() 1840 { 1841 assert(six == 6); 1842 }''') 1843 1844.. @test('run', howmany='all') 1845 1846Note that if we had used ``binding< … >`` rather than ``value_type< … 1847>``, we would end up returning a reference to the temporary created in 1848the ``2 * …`` expression. 1849 1850__ binding_intro_ 1851 1852Lazy Default Computation 1853======================== 1854 1855When a default value is expensive to compute, it would be 1856preferable to avoid it until we're sure it's absolutely necessary. 1857``BOOST_PARAMETER_FUNCTION`` takes care of that problem for us, but 1858when using |ArgumentPack|\ s explicitly, we need a tool other than 1859``operator|``:: 1860 1861 BOOST_PARAMETER_NAME(s1) 1862 BOOST_PARAMETER_NAME(s2) 1863 BOOST_PARAMETER_NAME(s3) 1864 1865 template <class ArgumentPack> 1866 std::string f(ArgumentPack const& args) 1867 { 1868 std::string const& s1 = args[_s1]; 1869 std::string const& s2 = args[_s2]; 1870 typename parameter::binding< 1871 ArgumentPack,tag::s3,std::string 1872 >::type s3 = args[_s3|(s1+s2)]; // always constructs s1+s2 1873 return s3; 1874 } 1875 1876 std::string x = f((_s1="hello,", _s2=" world", _s3="hi world")); 1877 1878.. @example.prepend(''' 1879 #include <boost/parameter.hpp> 1880 #include <string> 1881 1882 namespace parameter = boost::parameter;''') 1883 1884.. @example.append(''' 1885 int main() 1886 {}''') 1887 1888.. @test('run') 1889 1890In the example above, the string ``"hello, world"`` is constructed 1891despite the fact that the user passed us a value for ``s3``. To 1892remedy that, we can compute the default value *lazily* (that is, 1893only on demand), by using ``boost::bind()`` to create a function 1894object. 1895 1896.. danielw: I'm leaving the text below in the source, because we might 1897.. want to change back to it after 1.34, and if I remove it now we 1898.. might forget about it. 1899 1900.. by combining the logical-or (“``||``”) operator 1901.. with a function object built by the Boost Lambda_ library: [#bind]_ 1902 1903.. parsed-literal:: 1904 1905 typename parameter::binding< 1906 ArgumentPack, tag::s3, std::string 1907 >::type s3 = args[_s3 1908 **|| boost::bind(std::plus<std::string>(), boost::ref(s1), boost::ref(s2))** ]; 1909 1910.. @example.prepend(''' 1911 #include <boost/bind.hpp> 1912 #include <boost/ref.hpp> 1913 #include <boost/parameter.hpp> 1914 #include <string> 1915 #include <functional> 1916 1917 namespace parameter = boost::parameter; 1918 1919 BOOST_PARAMETER_NAME(s1) 1920 BOOST_PARAMETER_NAME(s2) 1921 BOOST_PARAMETER_NAME(s3) 1922 1923 template <class ArgumentPack> 1924 std::string f(ArgumentPack const& args) 1925 { 1926 std::string const& s1 = args[_s1]; 1927 std::string const& s2 = args[_s2];''') 1928 1929.. @example.append(''' 1930 return s3; 1931 } 1932 1933 std::string x = f((_s1="hello,", _s2=" world", _s3="hi world")); 1934 1935 int main() 1936 {}''') 1937 1938.. @test('run') 1939 1940.. .. _Lambda: ../../../lambda/index.html 1941 1942.. sidebar:: Mnemonics 1943 1944 To remember the difference between ``|`` and ``||``, recall that 1945 ``||`` normally uses short-circuit evaluation: its second 1946 argument is only evaluated if its first argument is ``false``. 1947 Similarly, in ``color_map[param||f]``, ``f`` is only invoked if 1948 no ``color_map`` argument was supplied. 1949 1950The expression ``bind(std::plus<std::string>(), ref(s1), ref(s2))`` yields 1951a *function object* that, when invoked, adds the two strings together. 1952That function will only be invoked if no ``s3`` argument is supplied by 1953the caller. 1954 1955.. The expression ``lambda::var(s1)+lambda::var(s2)`` yields a 1956.. *function object* that, when invoked, adds the two strings 1957.. together. That function will only be invoked if no ``s3`` argument 1958.. is supplied by the caller. 1959 1960================ 1961 Best Practices 1962================ 1963 1964By now you should have a fairly good idea of how to use the 1965Parameter library. This section points out a few more-marginal 1966issues that will help you use the library more effectively. 1967 1968-------------- 1969Keyword Naming 1970-------------- 1971 1972``BOOST_PARAMETER_NAME`` prepends a leading underscore to the names 1973of all our keyword objects in order to avoid the following 1974usually-silent bug: 1975 1976.. parsed-literal:: 1977 1978 namespace people 1979 { 1980 namespace tag { struct name; struct age; } 1981 1982 namespace // unnamed 1983 { 1984 boost::parameter::keyword<tag::name>& **name** 1985 = boost::parameter::keyword<tag::name>::instance; 1986 boost::parameter::keyword<tag::age>& **age** 1987 = boost::parameter::keyword<tag::age>::instance; 1988 } 1989 1990 BOOST_PARAMETER_FUNCTION( 1991 (void), g, tag, (optional (name, \*, "bob")(age, \*, 42))) 1992 { 1993 std::cout << name << ":" << age; 1994 } 1995 1996 void f(int age) 1997 { 1998 :vellipsis:`\ 1999 . 2000 . 2001 . 2002 ` 2003 g(**age** = 3); // whoops! 2004 } 2005 } 2006 2007.. @ignore() 2008 2009Although in the case above, the user was trying to pass the value 2010``3`` as the ``age`` parameter to ``g``, what happened instead 2011was that ``f``\ 's ``age`` argument got reassigned the value 3, 2012and was then passed as a positional argument to ``g``. Since 2013``g``'s first positional parameter is ``name``, the default value 2014for ``age`` is used, and g prints ``3:42``. Our leading 2015underscore naming convention that makes this problem less likely 2016to occur. 2017 2018In this particular case, the problem could have been detected if 2019f's ``age`` parameter had been made ``const``, which is always a 2020good idea whenever possible. Finally, we recommend that you use 2021an enclosing namespace for all your code, but particularly for 2022names with leading underscores. If we were to leave out the 2023``people`` namespace above, names in the global namespace 2024beginning with leading underscores—which are reserved to your C++ 2025compiler—might become irretrievably ambiguous with those in our 2026unnamed namespace. 2027 2028---------- 2029Namespaces 2030---------- 2031 2032In our examples we've always declared keyword objects in (an 2033unnamed namespace within) the same namespace as the 2034Boost.Parameter-enabled functions using those keywords: 2035 2036.. parsed-literal:: 2037 2038 namespace lib 2039 { 2040 **BOOST_PARAMETER_NAME(name) 2041 BOOST_PARAMETER_NAME(index)** 2042 2043 BOOST_PARAMETER_FUNCTION( 2044 (int), f, tag, 2045 (optional (name,*,"bob")(index,(int),1)) 2046 ) 2047 { 2048 std::cout << name << ":" << index << std::endl; 2049 return index; 2050 } 2051 } 2052 2053.. @example.prepend(''' 2054 #include <boost/parameter.hpp> 2055 #include <iostream>''') 2056.. @namespace_setup = str(example) 2057.. @ignore() 2058 2059Users of these functions have a few choices: 2060 20611. Full qualification: 2062 2063 .. parsed-literal:: 2064 2065 int x = **lib::**\ f(**lib::**\ _name = "jill", **lib::**\ _index = 1); 2066 2067 This approach is more verbose than many users would like. 2068 2069.. @example.prepend(namespace_setup) 2070.. @example.append('int main() {}') 2071.. @test('run') 2072 20732. Make keyword objects available through 2074 *using-declarations*: 2075 2076 .. parsed-literal:: 2077 2078 **using lib::_name; 2079 using lib::_index;** 2080 2081 int x = lib::f(_name = "jill", _index = 1); 2082 2083 This version is much better at the actual call site, but the 2084 *using-declarations* themselves can be verbose and hard-to 2085 manage. 2086 2087.. @example.prepend(namespace_setup) 2088.. @example.append('int main() {}') 2089.. @test('run') 2090 20913. Bring in the entire namespace with a *using-directive*: 2092 2093 .. parsed-literal:: 2094 2095 **using namespace lib;** 2096 int x = **f**\ (_name = "jill", _index = 3); 2097 2098 This option is convenient, but it indiscriminately makes the 2099 *entire* contents of ``lib`` available without qualification. 2100 2101.. @example.prepend(namespace_setup) 2102.. @example.append('int main() {}') 2103.. @test('run') 2104 2105If we add an additional namespace around keyword declarations, 2106though, we can give users more control: 2107 2108.. parsed-literal:: 2109 2110 namespace lib 2111 { 2112 **namespace keywords 2113 {** 2114 BOOST_PARAMETER_NAME(name) 2115 BOOST_PARAMETER_NAME(index) 2116 **}** 2117 2118 BOOST_PARAMETER_FUNCTION( 2119 (int), f, **keywords::**\ tag, 2120 (optional (name,*,"bob")(index,(int),1)) 2121 ) 2122 { 2123 std::cout << name << ":" << index << std::endl; 2124 return index; 2125 } 2126 } 2127 2128.. @example.prepend(''' 2129 #include <boost/parameter.hpp> 2130 #include <iostream>''') 2131 2132Now users need only a single *using-directive* to bring in just the 2133names of all keywords associated with ``lib``: 2134 2135.. parsed-literal:: 2136 2137 **using namespace lib::keywords;** 2138 int y = lib::f(_name = "bob", _index = 2); 2139 2140.. @example.append('int main() {}') 2141.. @test('run', howmany='all') 2142 2143------------- 2144Documentation 2145------------- 2146 2147The interface idioms enabled by Boost.Parameter are completely new 2148(to C++), and as such are not served by pre-existing documentation 2149conventions. 2150 2151.. Note:: This space is empty because we haven't settled on any 2152 best practices yet. We'd be very pleased to link to your 2153 documentation if you've got a style that you think is worth 2154 sharing. 2155 2156============================ 2157 Portability Considerations 2158============================ 2159 2160Use the `regression test results`_ for the latest Boost release of 2161the Parameter library to see how it fares on your favorite 2162compiler. Additionally, you may need to be aware of the following 2163issues and workarounds for particular compilers. 2164 2165.. _`regression test results`: http://www.boost.org/regression/release/user/parameter.html 2166 2167----------------- 2168No SFINAE Support 2169----------------- 2170 2171Some older compilers don't support SFINAE. If your compiler meets 2172that criterion, then Boost headers will ``#define`` the preprocessor 2173symbol ``BOOST_NO_SFINAE``, and parameter-enabled functions won't be 2174removed from the overload set based on their signatures. 2175 2176--------------------------- 2177No Support for |result_of|_ 2178--------------------------- 2179 2180.. |result_of| replace:: ``result_of`` 2181 2182.. _result_of: ../../../utility/utility.htm#result_of 2183 2184`Lazy default computation`_ relies on the |result_of| class 2185template to compute the types of default arguments given the type 2186of the function object that constructs them. On compilers that 2187don't support |result_of|, ``BOOST_NO_RESULT_OF`` will be 2188``#define``\ d, and the compiler will expect the function object to 2189contain a nested type name, ``result_type``, that indicates its 2190return type when invoked without arguments. To use an ordinary 2191function as a default generator on those compilers, you'll need to 2192wrap it in a class that provides ``result_type`` as a ``typedef`` 2193and invokes the function via its ``operator()``. 2194 2195.. 2196 Can't Declare |ParameterSpec| via ``typedef`` 2197 ============================================= 2198 2199 In principle you can declare a |ParameterSpec| as a ``typedef`` 2200 for a specialization of ``parameters<…>``, but Microsoft Visual C++ 2201 6.x has been seen to choke on that usage. The workaround is to use 2202 inheritance and declare your |ParameterSpec| as a class: 2203 2204 .. parsed-literal:: 2205 2206 **struct dfs_parameters 2207 :** parameter::parameters< 2208 tag::graph, tag::visitor, tag::root_vertex 2209 , tag::index_map, tag::color_map 2210 > **{};** 2211 2212 2213 Default Arguments Unsupported on Nested Templates 2214 ================================================= 2215 2216 As of this writing, Borland compilers don't support the use of 2217 default template arguments on member class templates. As a result, 2218 you have to supply ``BOOST_PARAMETER_MAX_ARITY`` arguments to every 2219 use of ``parameters<…>::match``. Since the actual defaults used 2220 are unspecified, the workaround is to use 2221 |BOOST_PARAMETER_MATCH|_ to declare default arguments for SFINAE. 2222 2223 .. |BOOST_PARAMETER_MATCH| replace:: ``BOOST_PARAMETER_MATCH`` 2224 2225-------------------------------------------------- 2226Compiler Can't See References In Unnamed Namespace 2227-------------------------------------------------- 2228 2229If you use Microsoft Visual C++ 6.x, you may find that the compiler 2230has trouble finding your keyword objects. This problem has been 2231observed, but only on this one compiler, and it disappeared as the 2232test code evolved, so we suggest you use it only as a last resort 2233rather than as a preventative measure. The solution is to add 2234*using-declarations* to force the names to be available in the 2235enclosing namespace without qualification:: 2236 2237 namespace graphs 2238 { 2239 using graphs::graph; 2240 using graphs::visitor; 2241 using graphs::root_vertex; 2242 using graphs::index_map; 2243 using graphs::color_map; 2244 } 2245 2246================ 2247 Python Binding 2248================ 2249 2250.. _python: python.html 2251 2252Follow `this link`__ for documentation on how to expose 2253Boost.Parameter-enabled functions to Python with `Boost.Python`_. 2254 2255__ python.html 2256 2257=========== 2258 Reference 2259=========== 2260 2261.. _reference: reference.html 2262 2263Follow `this link`__ to the Boost.Parameter reference 2264documentation. 2265 2266__ reference.html 2267 2268========== 2269 Glossary 2270========== 2271 2272.. _arguments: 2273 2274:Argument (or “actual argument”): the value actually passed to a 2275 function or class template 2276 2277.. _parameter: 2278 2279:Parameter (or “formal parameter”): the name used to refer to an 2280 argument within a function or class template. For example, the 2281 value of ``f``'s *parameter* ``x`` is given by the *argument* 2282 ``3``:: 2283 2284 int f(int x) { return x + 1 } 2285 int y = f(3); 2286 2287================== 2288 Acknowledgements 2289================== 2290 2291The authors would like to thank all the Boosters who participated 2292in the review of this library and its documentation, most 2293especially our review manager, Doug Gregor. 2294 2295-------------------------- 2296 2297.. [#old_interface] As of Boost 1.33.0 the Graph library was still 2298 using an `older named parameter mechanism`__, but there are 2299 plans to change it to use Boost.Parameter (this library) in an 2300 upcoming release, while keeping the old interface available for 2301 backward-compatibility. 2302 2303__ ../../../graph/doc/bgl_named_params.html 2304 2305.. [#odr] The **One Definition Rule** says that any given entity in 2306 a C++ program must have the same definition in all translation 2307 units (object files) that make up a program. 2308 2309.. [#vertex_descriptor] If you're not familiar with the Boost Graph 2310 Library, don't worry about the meaning of any 2311 Graph-library-specific details you encounter. In this case you 2312 could replace all mentions of vertex descriptor types with 2313 ``int`` in the text, and your understanding of the Parameter 2314 library wouldn't suffer. 2315 2316.. [#ConceptCpp] This is a major motivation behind `ConceptC++`_. 2317 2318.. _`ConceptC++`: http://www.generic-programming.org/software/ConceptGCC/ 2319 2320.. .. [#bind] The Lambda library is known not to work on `some 2321.. less-conformant compilers`__. When using one of those you could 2322.. use `Boost.Bind`_ to generate the function object:: 2323 2324.. boost::bind(std::plus<std::string>(),s1,s2) 2325 2326.. [#is_keyword_expression] Here we're assuming there's a predicate 2327 metafunction ``is_keyword_expression`` that can be used to 2328 identify models of Boost.Python's KeywordExpression concept. 2329 2330.. .. __ http://www.boost.org/regression/release/user/lambda.html 2331.. _Boost.Bind: ../../../bind/index.html 2332 2333 2334.. [#using] You can always give the illusion that the function 2335 lives in an outer namespace by applying a *using-declaration*:: 2336 2337 namespace foo_overloads 2338 { 2339 // foo declarations here 2340 void foo() { ... } 2341 ... 2342 } 2343 using foo_overloads::foo; 2344 2345 This technique for avoiding unintentional argument-dependent 2346 lookup is due to Herb Sutter. 2347 2348 2349.. [#sfinae] This capability depends on your compiler's support for SFINAE. 2350 **SFINAE**: **S**\ ubstitution **F**\ ailure **I**\ s 2351 **N**\ ot **A**\ n **E** rror. If type substitution during the 2352 instantiation of a function template results in an invalid type, 2353 no compilation error is emitted; instead the overload is removed 2354 from the overload set. By producing an invalid type in the 2355 function signature depending on the result of some condition, 2356 we can decide whether or not an overload is considered during overload 2357 resolution. The technique is formalized in 2358 the |enable_if|_ utility. Most recent compilers support SFINAE; 2359 on compilers that don't support it, the Boost config library 2360 will ``#define`` the symbol ``BOOST_NO_SFINAE``. 2361 See 2362 http://www.semantics.org/once_weakly/w02_SFINAE.pdf for more 2363 information on SFINAE. 2364 2365.. |enable_if| replace:: ``enable_if`` 2366.. _enable_if: ../../../utility/enable_if.html 2367 2368 2369