xref: /llvm-project/clang-tools-extra/docs/clang-tidy/checks/modernize/avoid-bind.rst (revision 6e566bc5523f743bc34a7e26f050f1f2b4d699a8)
1.. title:: clang-tidy - modernize-avoid-bind
2
3modernize-avoid-bind
4====================
5
6The check finds uses of ``std::bind`` and ``boost::bind`` and replaces them
7with lambdas. Lambdas will use value-capture unless reference capture is
8explicitly requested with ``std::ref`` or ``boost::ref``.
9
10It supports arbitrary callables including member functions, function objects,
11and free functions, and all variations thereof. Anything that you can pass
12to the first argument of ``bind`` should be diagnosable. Currently, the only
13known case where a fix-it is unsupported is when the same placeholder is
14specified multiple times in the parameter list.
15
16Given:
17
18.. code-block:: c++
19
20  int add(int x, int y) { return x + y; }
21
22Then:
23
24.. code-block:: c++
25
26  void f() {
27    int x = 2;
28    auto clj = std::bind(add, x, _1);
29  }
30
31is replaced by:
32
33.. code-block:: c++
34
35  void f() {
36    int x = 2;
37    auto clj = [=](auto && arg1) { return add(x, arg1); };
38  }
39
40``std::bind`` can be hard to read and can result in larger object files and
41binaries due to type information that will not be produced by equivalent
42lambdas.
43
44Options
45-------
46
47.. option:: PermissiveParameterList
48
49  If the option is set to `true`, the check will append ``auto&&...`` to the end
50  of every placeholder parameter list. Without this, it is possible for a fix-it
51  to perform an incorrect transformation in the case where the result of the ``bind``
52  is used in the context of a type erased functor such as ``std::function`` which
53  allows mismatched arguments. For example:
54
55
56.. code-block:: c++
57
58  int add(int x, int y) { return x + y; }
59  int foo() {
60    std::function<int(int,int)> ignore_args = std::bind(add, 2, 2);
61    return ignore_args(3, 3);
62  }
63
64is valid code, and returns `4`. The actual values passed to ``ignore_args`` are
65simply ignored. Without ``PermissiveParameterList``, this would be transformed into
66
67.. code-block:: c++
68
69  int add(int x, int y) { return x + y; }
70  int foo() {
71    std::function<int(int,int)> ignore_args = [] { return add(2, 2); }
72    return ignore_args(3, 3);
73  }
74
75which will *not* compile, since the lambda does not contain an ``operator()``
76that accepts 2 arguments. With permissive parameter list, it instead generates
77
78.. code-block:: c++
79
80  int add(int x, int y) { return x + y; }
81  int foo() {
82    std::function<int(int,int)> ignore_args = [](auto&&...) { return add(2, 2); }
83    return ignore_args(3, 3);
84  }
85
86which is correct.
87
88This check requires using C++14 or higher to run.
89