欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++ bind 函数学习笔记

程序员文章站 2022-05-11 23:17:17
...

std::bind的说明

simple(1)
template <class Fn, class... Args>
  /* unspecified */ bind (Fn&& fn, Args&&... args);
with return type (2)
template <class Ret, class Fn, class... Args>
  /* unspecified */ bind (Fn&& fn, Args&&... args);
Bind function arguments
Returns a function object based on fn, but with its arguments bound to args. (返回函数对象,不是一个函数指针)

Each argument may either be bound to a value or be a placeholder:
- If bound to a value, calling the returned function object will always use that value as argument. 
- If a placeholder, calling the returned function object forwards an argument passed to the call (the one whose order number is specified by the placeholder).

Calling the returned object returns the same type as fn, unless a specific return type is specified as Ret (2) (note that Ret is the only template parameter that cannot be implicitly deduced by the arguments passed to this function).

The type of the returned object has the following properties:
  • Its functional call returns the same as fn with its arguments bound to args... (or forwarded, for placeholders).
  • For (1), it may have a member result_type: if Fn is a pointer to function or member function type, it is defined as an alias of its return type. Otherwise, it is defined as Fn::result_type, if such a member type exists.
  • For (2), it has a member result_type, defined as an alias of Ret.
  • It is move-constructible and, if the type of all of its arguments are copy-constructible, it is also copy-constructible. Both constructors never throw, provided none of the corresponding constructors of the decay typesof Fn and Args... throw.

Parameters

fn
A function object, pointer to function or pointer to member.
Fn shall have a decay type which is move-constructible from fn.
args...
List of arguments to bind: either values, or placeholders.
The types in Args... shall have decay types which are move-constructible from their respective arguments in args....
If for any argument, its decay type is a reference_wrapper, it bounds to its referenced value instead.

Return value

A function object that, when called, calls fn with its arguments bound to args.

If fn is a pointer to member, the first argument expected by the returned function is an object of the class *fn is a member (or a reference to it, or a pointer to it).

--------------------------------------------------------------------------------------------

例子

#include <iostream>
#include <functional>
#include <string>
using namespace std;

bool lenLargethanLen(const string &s, string::size_type sz)
{
  return s.length() > sz;
}

int addSum(int a, int b, int c, int d, int e)
{
  return a + (-b) + c + d + e;
}

int SubTest(int a, int b)
{
  return a - b;
}

class AAAA {
public:
  double a, b;
  double addsum() { return a + b; }
  double addsum1(int c) { return a + b + c; }
  static void getPrint() { cout << "getPrint" << endl; }
};

int main()
{

  //绑定2个参数
  auto fun0 = bind(lenLargethanLen, string("11111"), 10);
  cout << boolalpha << fun0() << endl;      //false
  cout << boolalpha << fun0("111111111111111111111", 10) << endl;      //输入2个参数,不报错,但是依然返回false
  //绑定定1个参数
  auto fun1 = bind(lenLargethanLen, std::placeholders::_1, 10);
  cout << boolalpha << fun1("123123") << endl;      //false
  cout << boolalpha << fun1("123123",2) << endl; //输入2个参数,不报错,但是依然返回false

  auto fun2 = bind(lenLargethanLen, placeholders::_1, 6);
  cout << boolalpha << fun2("123123111") << endl; //true

  string temp_str("12345");
  auto fun2_1 = bind(lenLargethanLen, temp_str,placeholders::_2);
  cout <<"fun2_1(\"\", 4): "<< boolalpha << fun2_1("", 4) << endl; //true  第一个参数没有用,但是必须要输入,否则编译不过
  cout <<"fun2_1(\"\", 6): "<< boolalpha << fun2_1("",6)  << endl; //false 第一个参数没有用,但是必须要输入,否则编译不过

  //绑定0个参数
  auto fun2_2 = bind(lenLargethanLen, placeholders::_1, std::placeholders::_2);
  cout << boolalpha << fun2_2("123123111", 5) << endl; //true
  
  cout << typeid(fun0).name() << endl;
  cout << typeid(fun2).name() << endl;
  cout << typeid(fun2_1).name() << endl;
  cout << typeid(fun2_2).name() << endl;
 /* output
  class std::_Binder<struct std::_Unforced, bool(__cdecl&)(class std::basic_string<char, struct std::char_traits<char>, class std::allocator<char> > const &, unsigned int), //函数对象说明
    class std::basic_string<char, struct std::char_traits<char>, class std::allocator<char> >, int>   // 对象的参数,这里表示不用输入参数。其实输入参数也不会报错,但是输入的参数没有用
  
  class std::_Binder<struct std::_Unforced, bool(__cdecl&)(class std::basic_string<char, struct std::char_traits<char>, class std::allocator<char> > const &, unsigned int), //函数对象说明
    struct std::_Ph<1> const &, int>    //对象的参数,需要输入第1个参数(Ph place holder)
  class std::_Binder<struct std::_Unforced, bool (__cdecl&)(class std::basic_string<char,struct std::char_traits<char>, class std::allocator<char> > const &, unsigned int), //函数对象说明
    class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,struct std::_Ph<2> const &> //对象的参数,需要输入第2个参数,
  
  class std::_Binder<struct std::_Unforced, bool(__cdecl&)(class std::basic_string<char, struct std::char_traits<char>, class std::allocator<char> > const &, unsigned int),//函数对象说明
    struct std::_Ph<1> const &, struct std::_Ph<2> const &> //对象的参数,需要输入2个参数
 */

  //绑定0个参数
  auto fun_sub = bind(SubTest, placeholders::_1, placeholders::_2);
  cout << fun_sub(1, 2) << endl;  //-1
  cout << typeid(fun_sub).name() << endl;
  /* class std::_Binder<struct std::_Unforced,int (__cdecl&)(int,int),struct std::_Ph<1> const &,struct std::_Ph<2> const &> */

  //绑定其中的部分参数
  int a = 3, b = 4, c = 5;
  auto fun3 = bind(addSum, placeholders::_2, placeholders::_1, a, b, c);
  cout << fun3(1, 2) << endl; //13
  cout << fun3(1, 2,3,4,5) << endl; //13
  cout << typeid(fun3).name() << endl;
  /* class std::_Binder<struct std::_Unforced,int (__cdecl&)(int,int,int,int,int),struct std::_Ph<2> const &,struct std::_Ph<1> const &,int &,int &,int &> */

  auto fp2 = bind<int>(addSum, placeholders::_2, b, placeholders::_1, a, c);
  cout <<" fp2(7, 8) : "<< fp2(7, 8) << endl;   // fp2(7, 8) : 19   8 - 4(b) + 7 + 3(a) + 5(c)
  cout << typeid(fp2).name() << endl;
  /* class std::_Binder<int,int (__cdecl&)(int,int,int,int,int),struct std::_Ph<2> const &,int &,struct std::_Ph<1> const &,int &,int &> */

  auto fp3 = bind<int>(addSum, placeholders::_2, b, placeholders::_3, a, c);
  // cout << fp3(4, 3) << endl;      // error 但placeholder不是从1开始时,必须指定所有参数,否则编译错误
  cout <<"fp3(0, 2, 3, 0, 0) =  "<<fp3(0, 2, 3, 0, 0) << endl;  // fp3(0, 2, 3, 0, 0) =  9 = 3 - 4(b) + 2 + 3(a) + 5(c) 其中仅有第2,3个参数有效,其他参数没用,仅用于占位
  cout <<"fp3(111, 2, 3, -12314, 93) =  " << fp3(111, 2, 3, -12314, 93) << endl;  // fp3(111, 2, 3, -12314, 93) =  9  其中仅有第2,3个参数有效,其他参数没用,仅用于占位
  cout << typeid(fp3).name() << endl;
  /* class std::_Binder<int,int (__cdecl&)(int,int,int,int,int),struct std::_Ph<2> const &,int &,struct std::_Ph<3> const &,int &,int &> */

  class AAAA a1 { 1, 4 };
  //绑定成员函数
  auto bound_member_fn = bind(&AAAA::addsum, placeholders::_1);
  std::cout << bound_member_fn(a1) << endl;  // 5
  cout << typeid(bound_member_fn).name() << endl;
  /* class std::_Binder<struct std::_Unforced,double (__thiscall AAAA::*)(void),struct std::_Ph<1> const &>  */
 
  //绑定成员函数2
  auto bound_member_data2 = std::bind(&AAAA::addsum1, a1, placeholders::_1); // returns ten_two.a
  std::cout << bound_member_data2(23) << endl; // 28
  cout << typeid(bound_member_data2).name() << endl;
  //class std::_Binder<struct std::_Unforced,double (__thiscall AAAA::*)(int),class AAAA &,struct std::_Ph<1> const &>

   //绑定成员变量
  auto bound_member_data = std::bind(&AAAA::a, a1); // returns a1.a
  std::cout << bound_member_data() << endl;;  // 1
  cout << typeid(bound_member_data).name() << endl;
  // class std::_Binder<struct std::_Unforced,double AAAA::*,class AAAA &>

                                             //绑定静态成员函数
  auto bound_statis = std::bind(&AAAA::getPrint); // returns ten_two.a
  bound_statis();  //getPrint
  cout << typeid(bound_statis).name() << endl;  //class std::_Binder<struct std::_Unforced,void (__cdecl*)(void)>
  system("pause");
  return 0;
}

相关标签: bind