]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/bind/doc/bind/purpose.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / bind / doc / bind / purpose.qbk
1 [/
2 / Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
3 / Copyright (c) 2003-2008 Peter Dimov
4 /
5 / Distributed under the Boost Software License, Version 1.0. (See
6 / accompanying file LICENSE_1_0.txt or copy at
7 / http://www.boost.org/LICENSE_1_0.txt)
8 /]
9
10 [section:purpose Purpose]
11
12 `boost::bind` is a generalization of the standard functions `std::bind1st` and
13 `std::bind2nd`. It supports arbitrary function objects, functions, function
14 pointers, and member function pointers, and is able to bind any argument to a
15 specific value or route input arguments into arbitrary positions. `bind` does
16 not place any requirements on the function object; in particular, it does not
17 need the `result_type`, `first_argument_type` and `second_argument_type`
18 standard typedefs.
19
20 [section Using bind with functions and function pointers]
21
22 Given these definitions:
23
24 int f(int a, int b)
25 {
26 return a + b;
27 }
28
29 int g(int a, int b, int c)
30 {
31 return a + b + c;
32 }
33
34 `bind(f, 1, 2)` will produce a "nullary" function object that takes no
35 arguments and returns `f(1, 2)`. Similarly, `bind(g, 1, 2, 3)()` is equivalent
36 `to g(1, 2, 3)`.
37
38 It is possible to selectively bind only some of the arguments.
39 `bind(f, _1, 5)(x)` is equivalent to `f(x, 5)`; here `_1` is a /placeholder/
40 argument that means "substitute with the first input argument."
41
42 For comparison, here is the same operation expressed with the standard library
43 primitives:
44
45 std::bind2nd(std::ptr_fun(f), 5)(x);
46
47 `bind` covers the functionality of `std::bind1st` as well:
48
49 std::bind1st(std::ptr_fun(f), 5)(x); // f(5, x)
50 bind(f, 5, _1)(x); // f(5, x)
51
52 `bind` can handle functions with more than two arguments, and its argument
53 substitution mechanism is more general:
54
55 bind(f, _2, _1)(x, y); // f(y, x)
56 bind(g, _1, 9, _1)(x); // g(x, 9, x)
57 bind(g, _3, _3, _3)(x, y, z); // g(z, z, z)
58 bind(g, _1, _1, _1)(x, y, z); // g(x, x, x)
59
60 Note that, in the last example, the function object produced by
61 `bind(g, _1, _1, _1)` does not contain references to any arguments beyond the
62 first, but it can still be used with more than one argument. Any extra
63 arguments are silently ignored, just like the first and the second argument
64 are ignored in the third example.
65
66 The arguments that `bind` takes are copied and held internally by the returned
67 function object. For example, in the following code:
68
69 int i = 5;
70 bind(f, i, _1);
71
72 a copy of the value of `i` is stored into the function object.
73 [@boost:/libs/core/doc/html/core/ref.html `boost::ref`] and
74 [@boost:/libs/core/doc/html/core/ref.html `boost::cref`] can be used to make the function
75 object store a reference to an object, rather than a copy:
76
77 int i = 5;
78 bind(f, ref(i), _1);
79 bind(f, cref(i), _1);
80
81 [endsect]
82
83 [section:with_function_objects Using bind with function objects]
84
85 `bind` is not limited to functions; it accepts arbitrary function objects. In
86 the general case, the return type of the generated function object's
87 `operator()` has to be specified explicitly (without a `typeof` operator the
88 return type cannot be inferred):
89
90 struct F
91 {
92 int operator()(int a, int b) { return a - b; }
93 bool operator()(long a, long b) { return a == b; }
94 };
95
96 F f;
97 int x = 104;
98 bind<int>(f, _1, _1)(x); // f(x, x), i.e. zero
99
100 Some compilers have trouble with the `bind<R>(f, ...)` syntax. For portability
101 reasons, an alternative way to express the above is supported:
102
103 boost::bind(boost::type<int>(), f, _1, _1)(x);
104
105 Note, however, that the alternative syntax is provided only as a workaround.
106 It is not part of the interface.
107
108 When the function object exposes a nested type named `result_type`, the explicit
109 return type can be omitted:
110
111 int x = 8;
112 bind(std::less<int>(), _1, 9)(x); // x < 9
113
114 /[Note:/ the ability to omit the return type is not available on all compilers./]/
115
116 By default, `bind` makes a copy of the provided function object. `boost::ref`
117 and `boost::cref` can be used to make it store a reference to the function
118 object, rather than a copy. This can be useful when the function object is
119 non-copyable, expensive to copy, or contains state; of course, in this case
120 the programmer is expected to ensure that the function object is not destroyed
121 while it's still being used.
122
123 struct F2
124 {
125 int s;
126
127 typedef void result_type;
128 void operator()(int x) { s += x; }
129 };
130
131 F2 f2 = { 0 };
132 int a[] = { 1, 2, 3 };
133
134 std::for_each(a, a+3, bind(ref(f2), _1));
135
136 assert(f2.s == 6);
137
138 [endsect]
139
140 [section Using bind with pointers to members]
141
142 Pointers to member functions and pointers to data members are not function
143 objects, because they do not support `operator()`. For convenience, `bind`
144 accepts member pointers as its first argument, and the behavior is as if
145 [@boost:/libs/bind/mem_fn.html `boost::mem_fn`] has been used to convert the
146 member pointer into a function object. In other words, the expression
147
148 bind(&X::f, args)
149
150 is equivalent to
151
152 bind<R>(``[@boost:/libs/bind/mem_fn.html `mem_fn`]``(&X::f), args)
153
154 where `R` is the return type of `X::f` (for member functions) or the type of
155 the member (for data members.)
156
157 /[Note:/ `mem_fn` creates function objects that are able to accept a pointer,
158 a reference, or a smart pointer to an object as its first argument; for
159 additional information, see the `mem_fn`
160 [@boost:/libs/bind/mem_fn.html documentation]./]/
161
162 Example:
163
164 struct X
165 {
166 bool f(int a);
167 };
168
169 X x;
170 shared_ptr<X> p(new X);
171 int i = 5;
172
173 bind(&X::f, ref(x), _1)(i); // x.f(i)
174 bind(&X::f, &x, _1)(i); // (&x)->f(i)
175 bind(&X::f, x, _1)(i); // (internal copy of x).f(i)
176 bind(&X::f, p, _1)(i); // (internal copy of p)->f(i)
177
178 The last two examples are interesting in that they produce "self-contained"
179 function objects. `bind(&X::f, x, _1)` stores a copy of `x`.
180 `bind(&X::f, p, _1)` stores a copy of `p`, and since `p` is a
181 [@boost:/libs/smart_ptr/shared_ptr.htm `boost::shared_ptr`], the function
182 object retains a reference to its instance of `X` and will remain valid even
183 when `p` goes out of scope or is `reset()`.
184
185 [endsect]
186
187 [section Using nested binds for function composition]
188
189 Some of the arguments passed to `bind` may be nested /bind expressions/
190 themselves:
191
192 bind(f, bind(g, _1))(x); // f(g(x))
193
194 The inner /bind expressions/ are evaluated, in unspecified order, before the
195 outer `bind` when the function object is called; the results of the evaluation
196 are then substituted in their place when the outer `bind` is evaluated. In the
197 example above, when the function object is called with the argument list `(x)`,
198 `bind(g, _1)(x)` is evaluated first, yielding `g(x)`, and then
199 `bind(f, g(x))(x)` is evaluated, yielding the final result `f(g(x))`.
200
201 This feature of `bind` can be used to perform function composition. See
202 [@../../bind_as_compose.cpp bind_as_compose.cpp] for an example that
203 demonstrates how to use `bind` to achieve similar functionality to
204 [@http://www.boost.org/doc/libs/1_31_0/libs/compose/index.htm Boost.Compose].
205
206 Note that the first argument - the bound function object - is not evaluated,
207 even when it's a function object that is produced by `bind` or a /placeholder/
208 argument, so the example below does not work as expected:
209
210 typedef void (*pf)(int);
211
212 std::vector<pf> v;
213 std::for_each(v.begin(), v.end(), bind(_1, 5));
214
215 The desired effect can be achieved via a helper function object `apply` that
216 applies its first argument, as a function object, to the rest of its argument
217 list. For convenience, an implementation of `apply` is provided in the
218 [@../../../../boost/bind/apply.hpp apply.hpp] header file. Here is how the
219 modified version of the previous example looks like:
220
221 typedef void (*pf)(int);
222
223 std::vector<pf> v;
224 std::for_each(v.begin(), v.end(), bind(apply<void>(), _1, 5));
225
226 Although the first argument is, by default, not evaluated, all other arguments
227 are. Sometimes it is necessary not to evaluate arguments subsequent to the
228 first, even when they are nested /bind subexpressions/. This can be achieved
229 with the help of another function object, `protect`, that masks the type so
230 that `bind` does not recognize and evaluate it. When called, protect simply
231 forwards the argument list to the other function object unmodified.
232
233 The header [@../../../../boost/bind/protect.hpp protect.hpp] contains an
234 implementation of `protect`. To `protect` a bind function object from
235 evaluation, use `protect(bind(f, ...))`.
236
237 [endsect]
238
239 [section Overloaded operators (new in Boost 1.33)]
240
241 For convenience, the function objects produced by `bind` overload the logical
242 not operator `!` and the relational and logical operators `==, !=, <, <=, >,
243 >=, &&, ||`.
244
245 `!bind(f, ...)` is equivalent to `bind(logical_not(), bind(f, ...))`, where
246 `logical_not` is a function object that takes one argument `x` and returns
247 `!x`.
248
249 `bind(f, ...) op x`, where _op_ is a relational or logical operator, is
250 equivalent to `bind(relation(), bind(f, ...), x)`, where `relation` is a
251 function object that takes two arguments `a` and `b` and returns `a op b`.
252
253 What this means in practice is that you can conveniently negate the result of
254 `bind`:
255
256 std::remove_if(first, last, !bind(&X::visible, _1)); // remove invisible objects
257
258 and compare the result of `bind` against a value:
259
260 std::find_if(first, last, bind(&X::name, _1) == "Peter");
261 std::find_if(first, last, bind(&X::name, _1) == "Peter" || bind(&X::name, _1) == "Paul");
262
263 against a /placeholder/:
264
265 bind(&X::name, _1) == _2
266
267 or against another /bind expression/:
268
269 std::sort(first, last, bind(&X::name, _1) < bind(&X::name, _2)); // sort by name
270
271 [endsect]
272
273 [endsect]