modernize-avoid-bind¶
The check finds uses of std::bind
and boost::bind
and replaces them
with lambdas. Lambdas will use value-capture unless reference capture is
explicitly requested with std::ref
or boost::ref
.
It supports arbitrary callables including member functions, function objects,
and free functions, and all variations thereof. Anything that you can pass
to the first argument of bind
should be diagnosable. Currently, the only
known case where a fix-it is unsupported is when the same placeholder is
specified multiple times in the parameter list.
Given:
int add(int x, int y) { return x + y; }
Then:
void f() {
int x = 2;
auto clj = std::bind(add, x, _1);
}
is replaced by:
void f() {
int x = 2;
auto clj = [=](auto && arg1) { return add(x, arg1); };
}
std::bind
can be hard to read and can result in larger object files and
binaries due to type information that will not be produced by equivalent
lambdas.
Options¶
- PermissiveParameterList¶
If the option is set to true, the check will append
auto&&...
to the end of every placeholder parameter list. Without this, it is possible for a fix-it to perform an incorrect transformation in the case where the result of thebind
is used in the context of a type erased functor such asstd::function
which allows mismatched arguments. For example:
int add(int x, int y) { return x + y; }
int foo() {
std::function<int(int,int)> ignore_args = std::bind(add, 2, 2);
return ignore_args(3, 3);
}
is valid code, and returns 4. The actual values passed to ignore_args
are
simply ignored. Without PermissiveParameterList
, this would be transformed into
int add(int x, int y) { return x + y; }
int foo() {
std::function<int(int,int)> ignore_args = [] { return add(2, 2); }
return ignore_args(3, 3);
}
which will not compile, since the lambda does not contain an operator()
that accepts 2 arguments. With permissive parameter list, it instead generates
int add(int x, int y) { return x + y; }
int foo() {
std::function<int(int,int)> ignore_args = [](auto&&...) { return add(2, 2); }
return ignore_args(3, 3);
}
which is correct.
This check requires using C++14 or higher to run.