9cf1f6e68d0a1af3a14aee90420f8b5e534811da
[platform/upstream/llvm.git] / clang-tools-extra / docs / clang-tidy / checks / modernize-avoid-bind.rst
1 .. title:: clang-tidy - modernize-avoid-bind
2
3 modernize-avoid-bind
4 ====================
5
6 The check finds uses of ``std::bind`` and ``boost::bind`` and replaces them
7 with lambdas. Lambdas will use value-capture unless reference capture is
8 explicitly requested with ``std::ref`` or ``boost::ref``.
9
10 It supports arbitrary callables including member functions, function objects,
11 and free functions, and all variations thereof. Anything that you can pass
12 to the first argument of ``bind`` should be diagnosable. Currently, the only
13 known case where a fix-it is unsupported is when the same placeholder is
14 specified multiple times in the parameter list.
15
16 Given:
17
18 .. code-block:: c++
19
20   int add(int x, int y) { return x + y; }
21
22 Then:
23
24 .. code-block:: c++
25
26   void f() {
27     int x = 2;
28     auto clj = std::bind(add, x, _1);
29   }
30
31 is 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
41 binaries due to type information that will not be produced by equivalent
42 lambdas.
43
44 Options
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
64 is valid code, and returns `4`. The actual values passed to ``ignore_args`` are
65 simply 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
75 which will *not* compile, since the lambda does not contain an ``operator()``
76 that 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
86 which is correct.
87   
88 This check requires using C++14 or higher to run.