bind1st and bind2nd are helper template functions that creates an adaptor to convert a binary function object into a unary function object by binding the first/second argument of the binary function to a specified value. bind1st and bind2nd can only bind to first or second argument and binds only one argument at any time. They are deprecated in C++11. bind is their replacement. To refresh your memory, an example of bind2nd is presented below.
#include <functional>
#include <algorithm>
#include <iostream>
using namespace std;
void main()
{
int arr[8] = { 1,2,3,6,7,8,9,12 };
cout << count_if(arr, arr+8, bind2nd(less<int>(), 5)); }
The code essentially counts any number which is less than 5. less is a binary function object (functor) whereas count_if takes in a unary function. Basically, we use bind2nd to bind 5 to the 2nd parameter of less. Now, let us look at how the code would change with using bind.
#include <functional>
#include <algorithm>
#include <iostream>
using namespace std;
using namespace std::placeholders;
void main()
{
int arr[8] = { 1,2,3,6,7,8,9,12 };
cout << count_if(arr, arr+8, bind(less<int>(), _1, 5)); }
bind makes use of a placeholder, _1 to bind the integer argument (from the array) while 5 is the second argument. bind can also bind function pointer and member function as shown below.
#include <functional>
#include <algorithm>
#include <iostream>
using namespace std;
using namespace std::placeholders;
class MyCompare
{
public:
bool Less(int a, int b) const
{
return a < b;
}
};
void main()
{
int arr[8] = { 1,2,3,6,7,8,9,12 };
MyCompare comp;
cout << count_if(arr, arr+8, bind(&MyCompare::Less, comp, _1, 5)); }
For some C++ programmers who may prefer lambdas over bind. lambda is also known as anonymous function. bind produces function object where compiler does not have much free hand as with lambda to perform some performance optimization such as inlining. However, there are a couple of things, that are possible with bind but not with lambdas: bind can be used to bind move-only types and bind allows you to implement compile-time polymorphic behavior in template function. Both of these topic are out of scope in this tip/trick.
#include <functional>
#include <algorithm>
#include <iostream>
using namespace std;
void main()
{
int arr[8] = { 1,2,3,6,7,8,9,12 };
int lessThan = 5;
cout << count_if(arr, arr+8, [lessThan](int a) -> bool {
less<int> comp;
return comp(a, lessThan);
}); }
If the predicate function is trivial, we can just implement it inside the lambda as in our case. When a lambda only consists of a return expression, the compiler can deduce its return type without the user specifying it. As with previous example, we capture lessThan into the lambda.
#include <functional>
#include <algorithm>
#include <iostream>
using namespace std;
void main()
{
int arr[8] = { 1,2,3,6,7,8,9,12 };
int lessThan = 5;
cout << count_if(arr, arr+8, [lessThan](int a) {
return a < lessThan;
}); }
For simplicity, always prefer bind over the deprecated bind1st/bind2nd. Well for some programmers, lambda may be their preferable choice.