blob: c97c86d414eda1fccce4cd96a522cf7ed6c872c4 [file] [log] [blame] [view]
tzik7c0c0cf12016-10-05 08:14:051# Callback<> and Bind()
tzik703f1562016-09-02 07:36:552
Raphael Kubo da Costa17c1618c2019-03-28 19:30:443[TOC]
4
tzika4313512016-09-06 06:51:125## Introduction
tzik703f1562016-09-02 07:36:556
Brett Wilson508162c2017-09-27 22:24:467The templated `base::Callback<>` class is a generalized function object.
8Together with the `base::Bind()` function in base/bind.h, they provide a
9type-safe method for performing partial application of functions.
tzik703f1562016-09-02 07:36:5510
Matt Giuca7e81b22e2019-12-12 02:41:2111Partial application is the process of binding a subset of a function's arguments
12to produce another function that takes fewer arguments. This can be used to pass
13around a unit of delayed execution, much like lexical closures are used in other
14languages. For example, it is used in Chromium code to schedule tasks on
15different MessageLoops.
tzik703f1562016-09-02 07:36:5516
Brett Wilson508162c2017-09-27 22:24:4617A callback with no unbound input parameters (`base::Callback<void()>`) is
18called a `base::Closure`. Note that this is NOT the same as what other
19languages refer to as a closure -- it does not retain a reference to its
20enclosing environment.
tzik703f1562016-09-02 07:36:5521
tzik7c0c0cf12016-10-05 08:14:0522### OnceCallback<> And RepeatingCallback<>
23
Brett Wilson508162c2017-09-27 22:24:4624`base::OnceCallback<>` and `base::RepeatingCallback<>` are next gen callback
25classes, which are under development.
tzik7c0c0cf12016-10-05 08:14:0526
Brett Wilson508162c2017-09-27 22:24:4627`base::OnceCallback<>` is created by `base::BindOnce()`. This is a callback
28variant that is a move-only type and can be run only once. This moves out bound
29parameters from its internal storage to the bound function by default, so it's
30easier to use with movable types. This should be the preferred callback type:
31since the lifetime of the callback is clear, it's simpler to reason about when
32a callback that is passed between threads is destroyed.
tzik7c0c0cf12016-10-05 08:14:0533
Brett Wilson508162c2017-09-27 22:24:4634`base::RepeatingCallback<>` is created by `base::BindRepeating()`. This is a
35callback variant that is copyable that can be run multiple times. It uses
36internal ref-counting to make copies cheap. However, since ownership is shared,
37it is harder to reason about when the callback and the bound state are
38destroyed, especially when the callback is passed between threads.
tzik7c0c0cf12016-10-05 08:14:0539
Brett Wilson508162c2017-09-27 22:24:4640The legacy `base::Callback<>` is currently aliased to
41`base::RepeatingCallback<>`. In new code, prefer `base::OnceCallback<>` where
42possible, and use `base::RepeatingCallback<>` otherwise. Once the migration is
43complete, the type alias will be removed and `base::OnceCallback<>` will be renamed
44to `base::Callback<>` to emphasize that it should be preferred.
tzik7c0c0cf12016-10-05 08:14:0545
Brett Wilson508162c2017-09-27 22:24:4646`base::RepeatingCallback<>` is convertible to `base::OnceCallback<>` by the
47implicit conversion.
tzik7c0c0cf12016-10-05 08:14:0548
tzika4313512016-09-06 06:51:1249### Memory Management And Passing
tzik703f1562016-09-02 07:36:5550
danakje26d7cf2019-05-29 20:04:1451Pass `base::{Once,Repeating}Callback` objects by value if ownership is
52transferred; otherwise, pass it by const-reference.
tzik703f1562016-09-02 07:36:5553
tzik7c0c0cf12016-10-05 08:14:0554```cpp
55// |Foo| just refers to |cb| but doesn't store it nor consume it.
Brett Wilson508162c2017-09-27 22:24:4656bool Foo(const base::OnceCallback<void(int)>& cb) {
tzik7c0c0cf12016-10-05 08:14:0557 return cb.is_null();
58}
59
60// |Bar| takes the ownership of |cb| and stores |cb| into |g_cb|.
danakje26d7cf2019-05-29 20:04:1461base::RepeatingCallback<void(int)> g_cb;
62void Bar(base::RepeatingCallback<void(int)> cb) {
tzik7c0c0cf12016-10-05 08:14:0563 g_cb = std::move(cb);
64}
65
66// |Baz| takes the ownership of |cb| and consumes |cb| by Run().
Brett Wilson508162c2017-09-27 22:24:4667void Baz(base::OnceCallback<void(int)> cb) {
tzik7c0c0cf12016-10-05 08:14:0568 std::move(cb).Run(42);
69}
70
71// |Qux| takes the ownership of |cb| and transfers ownership to PostTask(),
72// which also takes the ownership of |cb|.
danakje26d7cf2019-05-29 20:04:1473void Qux(base::RepeatingCallback<void(int)> cb) {
74 PostTask(FROM_HERE, base::BindOnce(cb, 42));
75 PostTask(FROM_HERE, base::BindOnce(std::move(cb), 43));
tzik7c0c0cf12016-10-05 08:14:0576}
77```
78
danakje26d7cf2019-05-29 20:04:1479When you pass a `base::{Once,Repeating}Callback` object to a function parameter,
80use `std::move()` if you don't need to keep a reference to it, otherwise, pass the
Brett Wilson508162c2017-09-27 22:24:4681object directly. You may see a compile error when the function requires the
82exclusive ownership, and you didn't pass the callback by move. Note that the
danakje26d7cf2019-05-29 20:04:1483moved-from `base::{Once,Repeating}Callback` becomes null, as if its `Reset()`
84method had been called. Afterward, its `is_null()` method will return true and
85its `operator bool()` will return false.
tzik703f1562016-09-02 07:36:5586
danakjfcc5e7c2020-10-23 17:43:2787### Chaining callbacks
88
89When you have 2 callbacks that you wish to run in sequence, they can be joined
90together into a single callback through the use of `Then()`.
91
92Calling `Then()` on a `base::OnceCallback` joins a second callback that will be
93run together with, but after, the first callback. The return value from the
94first callback is passed along to the second, and the return value from the
95second callback is returned at the end. More concretely, calling `a.Then(b)`
96produces a new `base::OnceCallback` that will run `b(a());`, returning the
97result from `b`.
98
99This example uses `Then()` to join 2 `base::OnceCallback`s together:
100```cpp
101int Floor(float f) { return std::floor(f); }
102std::string IntToString(int i) { return base::NumberToString(i); }
103
104base::OnceCallback<int(float)> first = base::BindOnce(&Floor);
105base::OnceCallback<std::string(int)> second = base::BindOnce(&IntToString);
106
107// This will run |first|, run and pass the result to |second|, then return
108// the result from |second|.
109std::string r = std::move(first).Then(std::move(second)).Run(3.5f);
110// |r| will be "3". |first| and |second| are now both null, as they were
111// consumed to perform the join operation.
112```
113
114Similarly, `Then()` also works with `base::RepeatingCallback`; however, the
115joined callback must also be a `base::RepeatingCallback` to ensure the resulting
116callback can be invoked multiple times.
117
118This example uses `Then()` to join 2 `base::RepeatingCallback`s together:
119```cpp
120int Floor(float f) { return std::floor(f); }
121std::string IntToString(int i) { return base::NumberToString(i); }
122
123base::RepeatingCallback<int(float)> first = base::BindRepeating(&Floor);
124base::RepeatingCallback<std::string(int)> second = base::BindRepeating(&IntToString);
125
126// This creates a RepeatingCallback that will run |first|, run and pass the
127// result to |second|, then return the result from |second|.
128base::RepeatingCallback<std::string(float)> joined =
129 std::move(first).Then(std::move(second));
130// |first| and |second| are now both null, as they were consumed to perform
131// the join operation.
132
133// This runs the functor that was originally bound to |first|, then |second|.
134std::string r = joined.Run(3.5);
135// |r| will be "3".
136
137// It's valid to call it multiple times since all callbacks involved are
138// base::RepeatingCallbacks.
139r = joined.Run(2.5);
140// |r| is set to "2".
141```
142
143In the above example, casting the `base::RepeatingCallback` to an r-value with
144`std::move()` causes `Then()` to destroy the original callback, in the same way
145that occurs for joining `base::OnceCallback`s. However since a
146`base::RepeatingCallback` can be run multiple times, it can be joined
147non-destructively as well.
148```cpp
149int Floor(float f) { return std::floor(f); }
150std::string IntToString(int i) { return base::NumberToString(i); }
151
152base::RepeatingCallback<int(float)> first = base::BindRepeating(&Floor);
153base::RepeatingCallback<std::string(int)> second = base::BindRepeating(&IntToString);
154
155// This creates a RepeatingCallback that will run |first|, run and pass the
156// result to |second|, then return the result from |second|.
157std::string r = first.Then(second).Run(3.5f);
158// |r| will be 3, and |first| and |second| are still valid to use.
159
160// Runs Floor().
161int i = first.Run(5.5);
162// Runs IntToString().
163std::string s = second.Run(9);
164```
165
danakj9335cb1c2020-10-28 20:21:21166If the second callback does not want to receive a value from the first callback,
167you may use `base::IgnoreResult` to drop the return value in between running the
168two.
169
170```cpp
171// Returns an integer.
172base::RepeatingCallback<int()> first = base::BindRepeating([](){ return 5; });
173// Does not want to receive an integer.
174base::RepeatingClosure second = base::BindRepeating([](){});
175
176// This will not compile, because |second| can not receive the return value from
177// |first|.
178// first.Then(second).Run();
179
180// We can drop the result from |first| before running second.
181base::BindRepeating(base::IgnoreResult(first)).Then(second).Run();
182// This will effectively create a callback that when Run() will call
183// `first(); second();` instead of `second(first());`.
184```
185
186Note that the return value from |first| will be lost in the above example, and
187would be destroyed before |second| is run. If you want the return value from
188|first| to be preserved and ultimately returned after running both |first| and
189|second|, then you would need a primitive such as the `base::PassThrough<T>()`
190helper in the [base::PassThrough CL](https://chromium-review.googlesource.com/c/chromium/src/+/2493243).
191If this would be helpful for you, please let [email protected] know or ping
192the CL.
193
kylechardde7d232020-11-16 17:35:09194### Chaining callbacks across different task runners
195
196```cpp
197// The task runner for a different thread.
198scoped_refptr<base::SequencedTaskRunner> other_task_runner = ...;
199
200// A function to compute some interesting result, except it can only be run
201// safely from `other_task_runner` and not the current thread.
202int ComputeResult();
203
204base::OnceCallback<int()> compute_result_cb = base::BindOnce(&ComputeResult);
205
206// Task runner for the current thread.
207scoped_refptr<base::SequencedTaskRunner> current_task_runner =
208 base::SequencedTaskRunnerHandle::Get();
209
210// A function to accept the result, except it can only be run safely from the
211// current thread.
212void ProvideResult(int result);
213
214base::OnceCallback<void(int)> provide_result_cb =
215 base::BindOnce(&ProvideResult);
216```
217
218Using `Then()` to join `compute_result_cb` and `provide_result_cb` directly
219would be inappropriate. `ComputeResult()` and `ProvideResult()` would run on the
220same thread which isn't safe. However, `base::BindPostTask()` can be used to
221ensure `provide_result_cb` will run on `current_task_runner`.
222
223```cpp
224// The following two statements post a task to `other_task_runner` to run
225// `task`. This will invoke ComputeResult() on a different thread to get the
226// result value then post a task back to `current_task_runner` to invoke
227// ProvideResult() with the result.
228OnceClosure task =
229 std::move(compute_result_cb)
230 .Then(base::BindPostTask(current_task_runner,
231 std::move(provide_result_cb)));
232other_task_runner->PostTask(FROM_HERE, std::move(task));
233```
234
Thomas Guilbert5db52382020-12-17 22:33:14235### Splitting a OnceCallback in two
236
237If a callback is only run once, but two references need to be held to the
238callback, using a `base::OnceCallback` can be clearer than a
239`base::RepeatingCallback`, from an intent and semantics point of view.
240`base::SplitOnceCallback()` takes a `base::OnceCallback` and returns a pair of
241callbacks with the same signature. When either of the returned callback is run,
242the original callback is invoked. Running the leftover callback will result in a
243crash.
244This can be useful when passing a `base::OnceCallback` to a function that may or
245may not take ownership of the callback. E.g, when an object creation could fail:
246
247```cpp
248std::unique_ptr<FooTask> CreateFooTask(base::OnceClosure task) {
249 std::pair<base::OnceClosure,base::OnceClosure> split
250 = base::SplitOnceCallback(std::move(task));
251
252 std::unique_ptr<FooTask> foo = TryCreateFooTask(std::move(split.first));
253 if (foo)
254 return foo;
255
256 return CreateFallbackFooTask(std::move(split.second));
257}
258```
259
260While it is best to use a single callback to report success/failure, some APIs
261already take multiple callbacks. `base::SplitOnceCallback()` can be used to
262split a completion callback and help in such a case:
263
264```cpp
265using StatusCallback = base::OnceCallback<void(FooStatus)>;
266void DoOperation(StatusCallback done_cb) {
267 std::pair<StatusCallback, StatusCallback> split
268 = base::SplitOnceCallback(std::move(done_cb));
269
270 InnerWork(BindOnce(std::move(split.first), STATUS_OK),
271 BindOnce(std::move(split.second), STATUS_ABORTED));
272}
273
274void InnerWork(base::OnceClosure work_done_cb,
275 base::OnceClosure work_aborted_cb);
276```
277
tzika4313512016-09-06 06:51:12278## Quick reference for basic stuff
tzik703f1562016-09-02 07:36:55279
tzika4313512016-09-06 06:51:12280### Binding A Bare Function
tzik703f1562016-09-02 07:36:55281
282```cpp
283int Return5() { return 5; }
Brett Wilson508162c2017-09-27 22:24:46284base::OnceCallback<int()> func_cb = base::BindOnce(&Return5);
tzik7c0c0cf12016-10-05 08:14:05285LOG(INFO) << std::move(func_cb).Run(); // Prints 5.
286```
287
288```cpp
289int Return5() { return 5; }
Brett Wilson508162c2017-09-27 22:24:46290base::RepeatingCallback<int()> func_cb = base::BindRepeating(&Return5);
tzik703f1562016-09-02 07:36:55291LOG(INFO) << func_cb.Run(); // Prints 5.
292```
293
tzik7c0c0cf12016-10-05 08:14:05294### Binding A Captureless Lambda
295
296```cpp
Brett Wilson508162c2017-09-27 22:24:46297base::Callback<int()> lambda_cb = base::Bind([] { return 4; });
tzik7c0c0cf12016-10-05 08:14:05298LOG(INFO) << lambda_cb.Run(); // Print 4.
299
Brett Wilson508162c2017-09-27 22:24:46300base::OnceCallback<int()> lambda_cb2 = base::BindOnce([] { return 3; });
tzik7c0c0cf12016-10-05 08:14:05301LOG(INFO) << std::move(lambda_cb2).Run(); // Print 3.
Erik Chen9425c0f2020-09-11 21:41:09302
303base::OnceCallback<int()> lambda_cb3 = base::BindOnce([] { return 2; });
304base::OnceCallback<int(base::OnceCallback<int()>)> lambda_cb4 =
305 base::BindOnce(
306 [](base::OnceCallback<int()> callback) {
307 return std::move(callback).Run(); },
308 std::move(lambda_cb3));
309LOG(INFO) << std::move(lambda_cb4).Run(); // Print 2.
310
tzik7c0c0cf12016-10-05 08:14:05311```
312
Raphael Kubo da Costa17c1618c2019-03-28 19:30:44313### Binding A Capturing Lambda (In Tests)
314
315When writing tests, it is often useful to capture arguments that need to be
316modified in a callback.
317
318``` cpp
Guido Urdanetaef4e91942020-11-09 15:06:24319#include "base/test/bind.h"
Raphael Kubo da Costa17c1618c2019-03-28 19:30:44320
321int i = 2;
322base::Callback<void()> lambda_cb = base::BindLambdaForTesting([&]() { i++; });
323lambda_cb.Run();
324LOG(INFO) << i; // Print 3;
325```
326
tzika4313512016-09-06 06:51:12327### Binding A Class Method
tzik703f1562016-09-02 07:36:55328
tzika4313512016-09-06 06:51:12329The first argument to bind is the member function to call, the second is the
330object on which to call it.
tzik703f1562016-09-02 07:36:55331
332```cpp
Brett Wilson508162c2017-09-27 22:24:46333class Ref : public base::RefCountedThreadSafe<Ref> {
tzik703f1562016-09-02 07:36:55334 public:
335 int Foo() { return 3; }
tzik703f1562016-09-02 07:36:55336};
337scoped_refptr<Ref> ref = new Ref();
Brett Wilson508162c2017-09-27 22:24:46338base::Callback<void()> ref_cb = base::Bind(&Ref::Foo, ref);
tzik703f1562016-09-02 07:36:55339LOG(INFO) << ref_cb.Run(); // Prints out 3.
340```
341
342By default the object must support RefCounted or you will get a compiler
tzik7c0c0cf12016-10-05 08:14:05343error. If you're passing between threads, be sure it's RefCountedThreadSafe! See
344"Advanced binding of member functions" below if you don't want to use reference
345counting.
tzik703f1562016-09-02 07:36:55346
tzika4313512016-09-06 06:51:12347### Running A Callback
tzik703f1562016-09-02 07:36:55348
tzik7c0c0cf12016-10-05 08:14:05349Callbacks can be run with their `Run` method, which has the same signature as
Brett Wilson508162c2017-09-27 22:24:46350the template argument to the callback. Note that `base::OnceCallback::Run`
351consumes the callback object and can only be invoked on a callback rvalue.
tzik703f1562016-09-02 07:36:55352
353```cpp
Brett Wilson508162c2017-09-27 22:24:46354void DoSomething(const base::Callback<void(int, std::string)>& callback) {
tzik703f1562016-09-02 07:36:55355 callback.Run(5, "hello");
356}
tzik7c0c0cf12016-10-05 08:14:05357
Brett Wilson508162c2017-09-27 22:24:46358void DoSomethingOther(base::OnceCallback<void(int, std::string)> callback) {
tzik7c0c0cf12016-10-05 08:14:05359 std::move(callback).Run(5, "hello");
360}
tzik703f1562016-09-02 07:36:55361```
362
tzik7c0c0cf12016-10-05 08:14:05363RepeatingCallbacks can be run more than once (they don't get deleted or marked
Brett Wilson508162c2017-09-27 22:24:46364when run). However, this precludes using `base::Passed` (see below).
tzik703f1562016-09-02 07:36:55365
366```cpp
Brett Wilson508162c2017-09-27 22:24:46367void DoSomething(const base::RepeatingCallback<double(double)>& callback) {
tzik703f1562016-09-02 07:36:55368 double myresult = callback.Run(3.14159);
369 myresult += callback.Run(2.71828);
370}
371```
372
michaelpg0f156e12017-03-18 02:49:09373If running a callback could result in its own destruction (e.g., if the callback
374recipient deletes the object the callback is a member of), the callback should
Greg Thompsonddc84d42021-01-04 10:10:02375be moved or copied onto the stack before it can be safely invoked. (Note that
376this is only an issue for RepeatingCallbacks, because a OnceCallback always has
377to be moved for execution.)
michaelpg0f156e12017-03-18 02:49:09378
379```cpp
380void Foo::RunCallback() {
Bence Béky15327452018-05-10 20:59:07381 std::move(&foo_deleter_callback_).Run();
michaelpg0f156e12017-03-18 02:49:09382}
383```
384
Peter Kasting341e1fb2018-02-24 00:03:01385### Creating a Callback That Does Nothing
386
387Sometimes you need a callback that does nothing when run (e.g. test code that
388doesn't care to be notified about certain types of events). It may be tempting
389to pass a default-constructed callback of the right type:
390
391```cpp
392using MyCallback = base::OnceCallback<void(bool arg)>;
393void MyFunction(MyCallback callback) {
394 std::move(callback).Run(true); // Uh oh...
395}
396...
397MyFunction(MyCallback()); // ...this will crash when Run()!
398```
399
400Default-constructed callbacks are null, and thus cannot be Run(). Instead, use
401`base::DoNothing()`:
402
403```cpp
404...
405MyFunction(base::DoNothing()); // Can be Run(), will no-op
406```
407
408`base::DoNothing()` can be passed for any OnceCallback or RepeatingCallback that
409returns void.
410
411Implementation-wise, `base::DoNothing()` is actually a functor which produces a
412callback from `operator()`. This makes it unusable when trying to bind other
413arguments to it. Normally, the only reason to bind arguments to DoNothing() is
414to manage object lifetimes, and in these cases, you should strive to use idioms
415like DeleteSoon(), ReleaseSoon(), or RefCountedDeleteOnSequence instead. If you
416truly need to bind an argument to DoNothing(), or if you need to explicitly
417create a callback object (because implicit conversion through operator()() won't
418compile), you can instantiate directly:
419
420```cpp
421// Binds |foo_ptr| to a no-op OnceCallback takes a scoped_refptr<Foo>.
422// ANTIPATTERN WARNING: This should likely be changed to ReleaseSoon()!
423base::Bind(base::DoNothing::Once<scoped_refptr<Foo>>(), foo_ptr);
424```
425
tzika4313512016-09-06 06:51:12426### Passing Unbound Input Parameters
tzik703f1562016-09-02 07:36:55427
428Unbound parameters are specified at the time a callback is `Run()`. They are
Brett Wilson508162c2017-09-27 22:24:46429specified in the `base::Callback` template type:
tzik703f1562016-09-02 07:36:55430
431```cpp
432void MyFunc(int i, const std::string& str) {}
Brett Wilson508162c2017-09-27 22:24:46433base::Callback<void(int, const std::string&)> cb = base::Bind(&MyFunc);
tzik703f1562016-09-02 07:36:55434cb.Run(23, "hello, world");
435```
436
tzika4313512016-09-06 06:51:12437### Passing Bound Input Parameters
tzik703f1562016-09-02 07:36:55438
tzika4313512016-09-06 06:51:12439Bound parameters are specified when you create the callback as arguments to
Brett Wilson508162c2017-09-27 22:24:46440`base::Bind()`. They will be passed to the function and the `Run()`ner of the
441callback doesn't see those values or even know that the function it's calling.
tzik703f1562016-09-02 07:36:55442
443```cpp
444void MyFunc(int i, const std::string& str) {}
Brett Wilson508162c2017-09-27 22:24:46445base::Callback<void()> cb = base::Bind(&MyFunc, 23, "hello world");
tzik703f1562016-09-02 07:36:55446cb.Run();
447```
448
Brett Wilson508162c2017-09-27 22:24:46449A callback with no unbound input parameters (`base::Callback<void()>`) is
450called a `base::Closure`. So we could have also written:
tzik703f1562016-09-02 07:36:55451
452```cpp
Brett Wilson508162c2017-09-27 22:24:46453base::Closure cb = base::Bind(&MyFunc, 23, "hello world");
tzik703f1562016-09-02 07:36:55454```
455
456When calling member functions, bound parameters just go after the object
457pointer.
458
459```cpp
Brett Wilson508162c2017-09-27 22:24:46460base::Closure cb = base::Bind(&MyClass::MyFunc, this, 23, "hello world");
tzik703f1562016-09-02 07:36:55461```
462
Matt Giuca7e81b22e2019-12-12 02:41:21463### Partial Binding Of Parameters
tzik703f1562016-09-02 07:36:55464
tzika4313512016-09-06 06:51:12465You can specify some parameters when you create the callback, and specify the
466rest when you execute the callback.
tzik703f1562016-09-02 07:36:55467
tzik703f1562016-09-02 07:36:55468When calling a function bound parameters are first, followed by unbound
469parameters.
470
Gabriel Charette90480312018-02-16 15:10:05471```cpp
472void ReadIntFromFile(const std::string& filename,
473 base::OnceCallback<void(int)> on_read);
474
475void DisplayIntWithPrefix(const std::string& prefix, int result) {
476 LOG(INFO) << prefix << result;
477}
478
479void AnotherFunc(const std::string& file) {
480 ReadIntFromFile(file, base::BindOnce(&DisplayIntWithPrefix, "MyPrefix: "));
481};
482```
483
Matt Giuca7e81b22e2019-12-12 02:41:21484This technique is known as [partial
485application](http://en.wikipedia.org/wiki/Partial_application). It should be
486used in lieu of creating an adapter class that holds the bound arguments. Notice
487also that the `"MyPrefix: "` argument is actually a `const char*`, while
488`DisplayIntWithPrefix` actually wants a `const std::string&`. Like normal
489function dispatch, `base::Bind`, will coerce parameter types if possible.
Gabriel Charette90480312018-02-16 15:10:05490
Max Morinb51cf512018-02-19 12:49:49491### Avoiding Copies With Callback Parameters
tzik7c0c0cf12016-10-05 08:14:05492
Max Morinb51cf512018-02-19 12:49:49493A parameter of `base::BindRepeating()` or `base::BindOnce()` is moved into its
494internal storage if it is passed as a rvalue.
tzik7c0c0cf12016-10-05 08:14:05495
496```cpp
497std::vector<int> v = {1, 2, 3};
498// |v| is moved into the internal storage without copy.
Brett Wilson508162c2017-09-27 22:24:46499base::Bind(&Foo, std::move(v));
tzik7c0c0cf12016-10-05 08:14:05500```
501
502```cpp
tzik7c0c0cf12016-10-05 08:14:05503// The vector is moved into the internal storage without copy.
Brett Wilson508162c2017-09-27 22:24:46504base::Bind(&Foo, std::vector<int>({1, 2, 3}));
tzik7c0c0cf12016-10-05 08:14:05505```
506
Max Morinb51cf512018-02-19 12:49:49507Arguments bound with `base::BindOnce()` are always moved, if possible, to the
508target function.
509A function parameter that is passed by value and has a move constructor will be
510moved instead of copied.
511This makes it easy to use move-only types with `base::BindOnce()`.
512
513In contrast, arguments bound with `base::BindRepeating()` are only moved to the
514target function if the argument is bound with `base::Passed()`.
515
516**DANGER**:
517A `base::RepeatingCallback` can only be run once if arguments were bound with
518`base::Passed()`.
519For this reason, avoid `base::Passed()`.
520If you know a callback will only be called once, prefer to refactor code to
521work with `base::OnceCallback` instead.
522
523Avoid using `base::Passed()` with `base::BindOnce()`, as `std::move()` does the
524same thing and is more familiar.
tzik7c0c0cf12016-10-05 08:14:05525
526```cpp
527void Foo(std::unique_ptr<int>) {}
Max Morinb51cf512018-02-19 12:49:49528auto p = std::make_unique<int>(42);
tzik7c0c0cf12016-10-05 08:14:05529
530// |p| is moved into the internal storage of Bind(), and moved out to |Foo|.
Brett Wilson508162c2017-09-27 22:24:46531base::BindOnce(&Foo, std::move(p));
Max Morinb51cf512018-02-19 12:49:49532base::BindRepeating(&Foo, base::Passed(&p)); // Ok, but subtle.
533base::BindRepeating(&Foo, base::Passed(std::move(p))); // Ok, but subtle.
tzik7c0c0cf12016-10-05 08:14:05534```
535
tzika4313512016-09-06 06:51:12536## Quick reference for advanced binding
tzik703f1562016-09-02 07:36:55537
tzika4313512016-09-06 06:51:12538### Binding A Class Method With Weak Pointers
tzik703f1562016-09-02 07:36:55539
Wez33276262019-06-21 00:11:20540If `MyClass` has a `base::WeakPtr<MyClass> weak_this_` member (see below)
541then a class method can be bound with:
542
tzik703f1562016-09-02 07:36:55543```cpp
Wez33276262019-06-21 00:11:20544base::Bind(&MyClass::Foo, weak_this_);
tzika4313512016-09-06 06:51:12545```
tzik703f1562016-09-02 07:36:55546
547The callback will not be run if the object has already been destroyed.
Brett Wilson508162c2017-09-27 22:24:46548
Wez33276262019-06-21 00:11:20549Note that class method callbacks bound to `base::WeakPtr`s may only be
550run on the same sequence on which the object will be destroyed, since otherwise
551execution of the callback might race with the object's deletion.
552
553To use `base::WeakPtr` with `base::Bind()`, `MyClass` will typically look like:
554
555```cpp
556class MyClass {
557public:
Jeremy Roman0dd0b2f2019-07-16 21:00:43558 MyClass() {
Wez33276262019-06-21 00:11:20559 weak_this_ = weak_factory_.GetWeakPtr();
560 }
561private:
562 base::WeakPtr<MyClass> weak_this_;
563 // MyClass member variables go here.
Jeremy Roman0dd0b2f2019-07-16 21:00:43564 base::WeakPtrFactory<MyClass> weak_factory_{this};
Wez33276262019-06-21 00:11:20565};
566```
567
568`weak_factory_` is the last member variable in `MyClass` so that it is
569destroyed first. This ensures that if any class methods bound to `weak_this_`
570are `Run()` during teardown, then they will not actually be executed.
571
572If `MyClass` only ever `base::Bind()`s and executes callbacks on the same
573sequence, then it is generally safe to call `weak_factory_.GetWeakPtr()` at the
574`base::Bind()` call, rather than taking a separate `weak_this_` during
575construction.
tzik703f1562016-09-02 07:36:55576
tzika4313512016-09-06 06:51:12577### Binding A Class Method With Manual Lifetime Management
tzik703f1562016-09-02 07:36:55578
579```cpp
Brett Wilson508162c2017-09-27 22:24:46580base::Bind(&MyClass::Foo, base::Unretained(this));
tzik703f1562016-09-02 07:36:55581```
582
tzika4313512016-09-06 06:51:12583This disables all lifetime management on the object. You're responsible for
584making sure the object is alive at the time of the call. You break it, you own
585it!
tzik703f1562016-09-02 07:36:55586
tzika4313512016-09-06 06:51:12587### Binding A Class Method And Having The Callback Own The Class
tzik703f1562016-09-02 07:36:55588
589```cpp
590MyClass* myclass = new MyClass;
Brett Wilson508162c2017-09-27 22:24:46591base::Bind(&MyClass::Foo, base::Owned(myclass));
tzik703f1562016-09-02 07:36:55592```
593
tzika4313512016-09-06 06:51:12594The object will be deleted when the callback is destroyed, even if it's not run
595(like if you post a task during shutdown). Potentially useful for "fire and
596forget" cases.
tzik703f1562016-09-02 07:36:55597
tzik7c0c0cf12016-10-05 08:14:05598Smart pointers (e.g. `std::unique_ptr<>`) are also supported as the receiver.
599
600```cpp
601std::unique_ptr<MyClass> myclass(new MyClass);
Brett Wilson508162c2017-09-27 22:24:46602base::Bind(&MyClass::Foo, std::move(myclass));
tzik7c0c0cf12016-10-05 08:14:05603```
604
tzika4313512016-09-06 06:51:12605### Ignoring Return Values
tzik703f1562016-09-02 07:36:55606
tzika4313512016-09-06 06:51:12607Sometimes you want to call a function that returns a value in a callback that
608doesn't expect a return value.
tzik703f1562016-09-02 07:36:55609
610```cpp
Wen Fandd472022021-03-12 01:31:09611int DoSomething(int arg) {
612 cout << arg << endl;
613 return arg;
614}
danakj9335cb1c2020-10-28 20:21:21615base::RepeatingCallback<void(int)> cb =
616 base::BindRepeating(IgnoreResult(&DoSomething));
617```
618
619Similarly, you may want to use an existing callback that returns a value in a
620place that expects a void return type.
621
622```cpp
623base::RepeatingCallback<int()> cb = base::BindRepeating([](){ return 5; });
624base::RepeatingClosure void_cb = base::BindRepeating(base::IgnoreResult(cb));
tzik703f1562016-09-02 07:36:55625```
626
tzika4313512016-09-06 06:51:12627## Quick reference for binding parameters to Bind()
tzik703f1562016-09-02 07:36:55628
Brett Wilson508162c2017-09-27 22:24:46629Bound parameters are specified as arguments to `base::Bind()` and are passed to
630the function. A callback with no parameters or no unbound parameters is called
631a `base::Closure` (`base::Callback<void()>` and `base::Closure` are the same
632thing).
tzik703f1562016-09-02 07:36:55633
tzika4313512016-09-06 06:51:12634### Passing Parameters Owned By The Callback
tzik703f1562016-09-02 07:36:55635
636```cpp
637void Foo(int* arg) { cout << *arg << endl; }
638int* pn = new int(1);
Brett Wilson508162c2017-09-27 22:24:46639base::Closure foo_callback = base::Bind(&foo, base::Owned(pn));
tzik703f1562016-09-02 07:36:55640```
641
tzika4313512016-09-06 06:51:12642The parameter will be deleted when the callback is destroyed, even if it's not
643run (like if you post a task during shutdown).
tzik703f1562016-09-02 07:36:55644
tzika4313512016-09-06 06:51:12645### Passing Parameters As A unique_ptr
tzik703f1562016-09-02 07:36:55646
647```cpp
648void TakesOwnership(std::unique_ptr<Foo> arg) {}
Max Morinb51cf512018-02-19 12:49:49649auto f = std::make_unique<Foo>();
tzik703f1562016-09-02 07:36:55650// f becomes null during the following call.
Max Morinb51cf512018-02-19 12:49:49651base::OnceClosure cb = base::BindOnce(&TakesOwnership, std::move(f));
tzik703f1562016-09-02 07:36:55652```
653
tzika4313512016-09-06 06:51:12654Ownership of the parameter will be with the callback until the callback is run,
655and then ownership is passed to the callback function. This means the callback
656can only be run once. If the callback is never run, it will delete the object
657when it's destroyed.
tzik703f1562016-09-02 07:36:55658
tzika4313512016-09-06 06:51:12659### Passing Parameters As A scoped_refptr
tzik703f1562016-09-02 07:36:55660
661```cpp
662void TakesOneRef(scoped_refptr<Foo> arg) {}
tzik7c0c0cf12016-10-05 08:14:05663scoped_refptr<Foo> f(new Foo);
Brett Wilson508162c2017-09-27 22:24:46664base::Closure cb = base::Bind(&TakesOneRef, f);
tzik703f1562016-09-02 07:36:55665```
666
tzika4313512016-09-06 06:51:12667This should "just work." The closure will take a reference as long as it is
668alive, and another reference will be taken for the called function.
tzik703f1562016-09-02 07:36:55669
tzik7c0c0cf12016-10-05 08:14:05670```cpp
671void DontTakeRef(Foo* arg) {}
672scoped_refptr<Foo> f(new Foo);
Brett Wilson508162c2017-09-27 22:24:46673base::Closure cb = base::Bind(&DontTakeRef, base::RetainedRef(f));
tzik7c0c0cf12016-10-05 08:14:05674```
675
Brett Wilson508162c2017-09-27 22:24:46676`base::RetainedRef` holds a reference to the object and passes a raw pointer to
tzik7c0c0cf12016-10-05 08:14:05677the object when the Callback is run.
678
tzika4313512016-09-06 06:51:12679### Passing Parameters By Reference
tzik703f1562016-09-02 07:36:55680
jdoerrie9d7236f62019-03-05 13:00:23681References are *copied* unless `std::ref` or `std::cref` is used. Example:
tzik703f1562016-09-02 07:36:55682
683```cpp
684void foo(const int& arg) { printf("%d %p\n", arg, &arg); }
685int n = 1;
Brett Wilson508162c2017-09-27 22:24:46686base::Closure has_copy = base::Bind(&foo, n);
jdoerrie9d7236f62019-03-05 13:00:23687base::Closure has_ref = base::Bind(&foo, std::cref(n));
tzik703f1562016-09-02 07:36:55688n = 2;
689foo(n); // Prints "2 0xaaaaaaaaaaaa"
690has_copy.Run(); // Prints "1 0xbbbbbbbbbbbb"
691has_ref.Run(); // Prints "2 0xaaaaaaaaaaaa"
692```
693
tzika4313512016-09-06 06:51:12694Normally parameters are copied in the closure.
jdoerrie9d7236f62019-03-05 13:00:23695**DANGER**: `std::ref` and `std::cref` store a (const) reference instead,
696referencing the original parameter. This means that you must ensure the object
697outlives the callback!
tzik703f1562016-09-02 07:36:55698
tzika4313512016-09-06 06:51:12699## Implementation notes
tzik703f1562016-09-02 07:36:55700
tzika4313512016-09-06 06:51:12701### Where Is This Design From:
tzik703f1562016-09-02 07:36:55702
Brett Wilson508162c2017-09-27 22:24:46703The design of `base::Callback` and `base::Bind` is heavily influenced by C++'s
704`tr1::function` / `tr1::bind`, and by the "Google Callback" system used inside
705Google.
tzik703f1562016-09-02 07:36:55706
tzik7c0c0cf12016-10-05 08:14:05707### Customizing the behavior
708
Brett Wilson508162c2017-09-27 22:24:46709There are several injection points that controls binding behavior from outside
710of its implementation.
tzik7c0c0cf12016-10-05 08:14:05711
712```cpp
Brett Wilson508162c2017-09-27 22:24:46713namespace base {
714
tzik7c0c0cf12016-10-05 08:14:05715template <typename Receiver>
716struct IsWeakReceiver {
717 static constexpr bool value = false;
718};
719
720template <typename Obj>
721struct UnwrapTraits {
722 template <typename T>
723 T&& Unwrap(T&& obj) {
724 return std::forward<T>(obj);
725 }
726};
Brett Wilson508162c2017-09-27 22:24:46727
728} // namespace base
tzik7c0c0cf12016-10-05 08:14:05729```
730
Brett Wilson508162c2017-09-27 22:24:46731If `base::IsWeakReceiver<Receiver>::value` is true on a receiver of a method,
732`base::Bind` checks if the receiver is evaluated to true and cancels the invocation
733if it's evaluated to false. You can specialize `base::IsWeakReceiver` to make
734an external smart pointer as a weak pointer.
tzik7c0c0cf12016-10-05 08:14:05735
Brett Wilson508162c2017-09-27 22:24:46736`base::UnwrapTraits<BoundObject>::Unwrap()` is called for each bound arguments
jdoerrie9d7236f62019-03-05 13:00:23737right before `base::Callback` calls the target function. You can specialize this
738to define an argument wrapper such as `base::Unretained`, `base::Owned`,
739`base::RetainedRef` and `base::Passed`.
tzik7c0c0cf12016-10-05 08:14:05740
tzika4313512016-09-06 06:51:12741### How The Implementation Works:
tzik703f1562016-09-02 07:36:55742
743There are three main components to the system:
Brett Wilson508162c2017-09-27 22:24:46744 1) The `base::Callback<>` classes.
745 2) The `base::Bind()` functions.
jdoerrie9d7236f62019-03-05 13:00:23746 3) The arguments wrappers (e.g., `base::Unretained()` and `base::Owned()`).
tzik703f1562016-09-02 07:36:55747
Brett Wilson508162c2017-09-27 22:24:46748The Callback classes represent a generic function pointer. Internally, it
749stores a refcounted piece of state that represents the target function and all
750its bound parameters. The `base::Callback` constructor takes a
751`base::BindStateBase*`, which is upcasted from a `base::BindState<>`. In the
752context of the constructor, the static type of this `base::BindState<>` pointer
753uniquely identifies the function it is representing, all its bound parameters,
754and a `Run()` method that is capable of invoking the target.
tzik703f1562016-09-02 07:36:55755
Brett Wilson508162c2017-09-27 22:24:46756`base::Bind()` creates the `base::BindState<>` that has the full static type,
757and erases the target function type as well as the types of the bound
758parameters. It does this by storing a pointer to the specific `Run()` function,
759and upcasting the state of `base::BindState<>*` to a `base::BindStateBase*`.
760This is safe as long as this `BindStateBase` pointer is only used with the
761stored `Run()` pointer.
tzik703f1562016-09-02 07:36:55762
Brett Wilson508162c2017-09-27 22:24:46763To `base::BindState<>` objects are created inside the `base::Bind()` functions.
tzik703f1562016-09-02 07:36:55764These functions, along with a set of internal templates, are responsible for
765
766 - Unwrapping the function signature into return type, and parameters
767 - Determining the number of parameters that are bound
768 - Creating the BindState storing the bound parameters
769 - Performing compile-time asserts to avoid error-prone behavior
Armando Miragliacce1eb42018-08-16 14:35:44770 - Returning a `Callback<>` with an arity matching the number of unbound
tzik703f1562016-09-02 07:36:55771 parameters and that knows the correct refcounting semantics for the
772 target object if we are binding a method.
773
Brett Wilson508162c2017-09-27 22:24:46774The `base::Bind` functions do the above using type-inference and variadic
775templates.
tzik703f1562016-09-02 07:36:55776
Brett Wilson508162c2017-09-27 22:24:46777By default `base::Bind()` will store copies of all bound parameters, and
778attempt to refcount a target object if the function being bound is a class
779method. These copies are created even if the function takes parameters as const
tzik703f1562016-09-02 07:36:55780references. (Binding to non-const references is forbidden, see bind.h.)
781
tzika4313512016-09-06 06:51:12782To change this behavior, we introduce a set of argument wrappers (e.g.,
jdoerrie9d7236f62019-03-05 13:00:23783`base::Unretained()`). These are simple container templates that are passed by
danakjdb9ae7942020-11-11 16:01:35784value, and wrap a pointer to argument. Each helper has a comment describing it
785in base/bind.h.
tzik703f1562016-09-02 07:36:55786
tzik7c0c0cf12016-10-05 08:14:05787These types are passed to the `Unwrap()` functions to modify the behavior of
Brett Wilson508162c2017-09-27 22:24:46788`base::Bind()`. The `Unwrap()` functions change behavior by doing partial
tzik7c0c0cf12016-10-05 08:14:05789specialization based on whether or not a parameter is a wrapper type.
tzik703f1562016-09-02 07:36:55790
jdoerrie9d7236f62019-03-05 13:00:23791`base::Unretained()` is specific to Chromium.
tzik703f1562016-09-02 07:36:55792
tzika4313512016-09-06 06:51:12793### Missing Functionality
tzik703f1562016-09-02 07:36:55794 - Binding arrays to functions that take a non-const pointer.
795 Example:
796```cpp
797void Foo(const char* ptr);
798void Bar(char* ptr);
Brett Wilson508162c2017-09-27 22:24:46799base::Bind(&Foo, "test");
800base::Bind(&Bar, "test"); // This fails because ptr is not const.
tzik703f1562016-09-02 07:36:55801```
Gayane Petrosyan7f716982018-03-09 15:17:34802 - In case of partial binding of parameters a possibility of having unbound
803 parameters before bound parameters. Example:
804```cpp
805void Foo(int x, bool y);
806base::Bind(&Foo, _1, false); // _1 is a placeholder.
807```
tzik703f1562016-09-02 07:36:55808
Brett Wilson508162c2017-09-27 22:24:46809If you are thinking of forward declaring `base::Callback` in your own header
810file, please include "base/callback_forward.h" instead.