1[/============================================================================== 2 Copyright (C) 2001-2010 Joel de Guzman 3 Copyright (C) 2001-2005 Dan Marsden 4 Copyright (C) 2001-2010 Thomas Heller 5 Copyright (C) 2015 John Fletcher 6 7 Distributed under the Boost Software License, Version 1.0. (See accompanying 8 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9===============================================================================/] 10 11[section Bind] 12 13['Binding] is the act of tying together a function to some arguments for 14deferred (lazy) evaluation. Named [link phoenix.modules.function lazy functions] 15require a bit of typing. Unlike (unnamed) lambda expressions, we need to write a 16functor somewhere offline, detached from the call site. If you wish to transform a 17plain function, member function or member variable to a lambda expression, `bind` 18is your friend. 19 20[note Take note that binding functions, member functions or member variables is 21monomorphic. Rather than binding functions, the preferred way is to write true 22generic and polymorphic [link phoenix.modules.function lazy functions].] 23 24There is a set of overloaded `bind` template functions. Each `bind(x)` 25function generates a suitable binder object. 26 27[section Binding Function Objects] 28 29 #include <boost/phoenix/bind/bind_function_object.hpp> 30 31Binding function objects serves two purposes: 32* Partial function application 33* Quick adaption of already existing function objects 34 35In order to deduce the return type of the function object, it has to implement 36the __boost_result_of__ protocol. If the bound function object is polymorphic, 37the resulting binding object is polymorphic. 38 39[endsect] 40 41[section Binding Functions] 42 43 #include <boost/phoenix/bind/bind_function.hpp> 44 45Example, given a function `foo`: 46 47 void foo(int n) 48 { 49 std::cout << n << std::endl; 50 } 51 52Here's how the function `foo` may be bound: 53 54 bind(&foo, arg1) 55 56This is now a full-fledged expression that can finally 57be evaluated by another function call invocation. A second function call will 58invoke the actual `foo` function. Example: 59 60 bind(&foo, arg1)(4); 61 62will print out "4". 63 64[endsect] 65[section Binding Member Functions] 66 67 #include <boost/phoenix/bind/bind_member_function.hpp> 68 69Binding member functions can be done similarly. A bound member function takes in 70a pointer or reference to an object as the first argument. For instance, given: 71 72 struct xyz 73 { 74 void foo(int) const; 75 }; 76 77`xyz`'s `foo` member function can be bound as: 78 79 bind(&xyz::foo, obj, arg1) // obj is an xyz object 80 81Take note that a lazy-member functions expects the first argument to be a 82pointer or reference to an object. Both the object (reference or pointer) and 83the arguments can be lazily bound. Examples: 84 85 xyz obj; 86 bind(&xyz::foo, arg1, arg2) // arg1.foo(arg2) 87 bind(&xyz::foo, obj, arg1) // obj.foo(arg1) 88 bind(&xyz::foo, obj, 100) // obj.foo(100) 89 90[endsect] 91[section Binding Member Variables] 92 93 #include <boost/phoenix/bind/bind_member_variable.hpp> 94 95Member variables can also be bound much like member functions. Member variables 96are not functions. Yet, like the [link phoenix.modules.core.references `ref(x)`] that 97acts like a nullary function returning a reference to the data, member variables, 98when bound, act like a unary function, taking in a pointer or reference to an 99object as its argument and returning a reference to the bound member variable. 100For instance, given: 101 102 struct xyz 103 { 104 int v; 105 }; 106 107`xyz::v` can be bound as: 108 109 bind(&xyz::v, obj) // obj is an xyz object 110 111As noted, just like the bound member function, a bound member variable also 112expects the first (and only) argument to be a pointer or reference to an object. 113The object (reference or pointer) can be lazily bound. Examples: 114 115 xyz obj; 116 bind(&xyz::v, arg1) // arg1.v 117 bind(&xyz::v, obj) // obj.v 118 bind(&xyz::v, arg1)(obj) = 4 // obj.v = 4 119 120[endsect] 121 122[section Compatibility with Boost.Bind] 123 124`phoenix::bind` passes the older testcases of the Boost.Bind library. For those cases it is completely compatible and interchangeable. Some newer cases have been added to Boost.Bind in 2015 and compatibility in those cases is not guaranteed. 125 126Further tests are needed to check compatibility with std::tr1::bind and std::bind from the C++11 standard. 127 128[endsect] 129 130[endsect] 131 132