Detailed explanation of bind function of c/c + + standard library

Keywords: C++ Lambda

Detailed explanation of bind function of standard library

bind function: receive a function name as a parameter to generate a new function.

auto newCallable = bind(callbale, arg_list);

Arg list may contain parameters such as 1, 2, etc., which are parameters of the new function newCallable.

In this blog Introduction to lambda expression In, we discussed the problem of the third parameter of find if. At that time, it was solved by lambda expression. With bind function, it can also be solved by bind function.

Solution: bind(check_size, _1, sz)

auto idx = find_if(svec.begin(),svec.end(),bind(check_size, _1, 6));

In fact, newCall= bind(check_size, _1, sz) returns a new function, newCall, which only takes one parameter, just to meet the requirements of find_if.

  • From the perspective of find if, ah, newCall is a function with one parameter. OK, no problem.
  • From the point of view of program apes, check Ju size is a function with two parameters. It just binds sz(6) to newCall in advance,
  • When we call newCall(s), we actually call check UU size (s, 6), which means that newCall also has two parameters, but the second parameter has a default value of 6. newCall (const string & S, size_t SZ = 6);, so when calling newCall, passing a parameter is enough.

Note: 1, 2, etc. are placed in the namespace placeholder, so use:

//_1. Set ﹣ in std::placeholders
using namespace std::placeholders;

bind parameter usage:

//g is a callable object with two parameters
auto g = bind(func, a, b, _2, c, _1);//func is a function with five arguments
//Call g(X, Y), equal to func(a, b, Y, c, X)

Example:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>

using namespace std;
//_1. Set ﹣ in std::placeholders                                                
using namespace std::placeholders;

bool check_size(const string &s, string::size_type sz){
  return s.size() >= sz;
}
bool shorter(const string &a, const string &b){
  return a.size() < b.size();
}
ostream& print(ostream& os, const string &s, const char &c){
  //c = ',';                                                                    
  return os << s << c;
}
int main(){

  /*                                                                            
  //Using bind to realize the same function as lambda                                              
  vector<string> svec{"aab","d","aa","bb","e","bbb"};                           
  stable_sort(svec.begin(),svec.end(),[](const string &a, const string &b){     
      return a.size() < b.size();                                               
    });                                                                         
  string::size_type sz = 3;                                                     
  auto idx = find_if(svec.begin(),svec.end(),bind(check_size, _1, sz));         
  cout << *idx << endl;                                                         
  idx = find_if(svec.begin(),svec.end(),[sz](const string &s){                  
      return s.size() >= sz;                                                    
    });                                                                         
  cout << *idx << endl;                                                         
  */

  /*                                                                            
  //Using bind to change the position of the parameter of the original function                                              
  //Ascending order                                                                        
  vector<string> svec{"aab","d","aa","bb","e","bbb"};                           
  sort(svec.begin(), svec.end(), shorter);                                      
  for(auto const &s : svec){                                                    
    cout << s << " ";                                                           
  }                                                                             
  cout << endl;                                                                 
  //Because the position of the shortcut parameter is changed, it becomes descending                                 
  sort(svec.begin(), svec.end(),bind(shorter, _2, _1));                         
  for(auto const &s : svec){                                                    
    cout << s << " ";                                                           
  }                                                                             
  cout << endl;                                                                 
  */

  //bind references must use ref or cref functions to convert objects into references, not&                 
  ostream &os = cout;
  const char c = ' ';
  vector<string> svec{"aab","d","aa","bb","e","bbb"};
  for_each(svec.begin(),svec.end(),[&os, c](const string &s){
      os << s << c;
    });
  os << endl;
  for_each(svec.begin(),svec.end(),bind(print, ref(os), _1, cref(c)));
  os << endl;
  cout << c << endl;

}

QQ group of mutual learning in c/c + +: 877684253

My wechat: xiaoshitou5854

Posted by matt2012 on Sun, 29 Dec 2019 07:07:54 -0800