C++ std::function 模板类学习笔记

以下内容来自于: http://en.cppreference.com/w/cpp/utility/functional/function  对例子进行了相应修改,用于学习更多的细节

Class template std::function is a general-purpose polymorphic function wrapper. Instances of std::function can store, copy, and invoke any Callable target -- functions, lambda expressionsbind expressions, or other function objects, as well as pointers to member functions and pointers to data members.

类模板 std::function是一个通用的多态函数wrapper, std::function的实例可以保存、拷贝、触发任何可调用的目标,包括函数、lambda表达式、bind表达式、函数对象、类成员函数指针、类数据成员指针

The stored callable object is called the target of std::function. If a std::function contains no target, it is called empty. Invoking the target of an empty std::function results in std::bad_function_call exception being thrown.

被保存的对象称为std::function的目标。

std::function satisfies the requirements of CopyConstructible and CopyAssignable.

std::function满足拷贝构造和赋值构造。

注意: 使用std::function绑定类成员函数时,如果直接绑定对象(不是对象指针)的成员函数时,会生成一些新的对象,这些对象可能并不是想要的。因此最好绑定对象指针的成员函数方式,例如一些的test 6

#include <iostream>
#include <functional>
#include <string>
using namespace std;
using std::placeholders::_1;
class Foo {
public:
  Foo(int num) : num_(num) { 
    cout << "Foo construct:  " << num_ << " num_ addr:" << &num_ << endl;
  }
  Foo(const Foo &f) { 
    cout << "copy construct:" << f.num_ << " num_ addr:" << &num_ << endl;  
    num_ = f.num_; 
  }
  
  Foo & operator= (const Foo &f) { 
    cout << "assign construct" << " num_ addr:" << &num_ << endl;  
    num_ = f.num_; 
    return *this; 
  }
  ~Foo() { cout << "Foo destruct: " << num_ <<" num_ addr:" << &num_ <<endl; }

  inline void print_add(int i) const { cout << num_ + i << endl; }

  int num_;
  int aaa[1024];
};

void print_num(int i)
{
  std::cout << i << '\n';
}

class PrintNum {
public:
  void operator() (int i) const {
    cout << i << endl;
  }
};

typedef std::function<void(int)> fun_test;
void fun1(fun_test fun, int iput) {
  fun(iput);
}

//--------------test 1----------------
//99
//f_display is : class std::function < void __cdecl(int)>
//42
//f_display_42 is : class std::function<void __cdecl(void)>
void test1()
{
  cout << "--------------test 1----------------" << endl;
  std::function< void(int) > f_display = print_num;
  f_display(99);
  cout << "f_display is: " << typeid(f_display).name() << endl;

  std::function<void()> f_display_42 = []() { print_num(42); };
  f_display_42();
  cout << "f_display_42 is: " << typeid(f_display_42).name() << endl;
}

//--------------test 2----------------
//Foo construct : 100 num_ addr : 001CE934
//111
//Foo construct : 12345 num_ addr : 001CD2F8
//12367
//Foo destruct: 12345 num_ addr : 001CD2F8
//f_add_display is : class std::function<void __cdecl(class Foo const &, int)>
//Foo destruct: 100 num_ addr : 001CE934
void test2()
{
  cout << "--------------test 2----------------" << endl;
  const Foo foo(100);
  //这是一个普通的函数对象,有两个参数
  std::function<void(const Foo&, int)> f_add_display = &Foo::print_add;
  f_add_display(foo, 11);
  f_add_display(12345, 22); // 12345调用构造函数,先生成一个Foo对象
  cout << "f_add_display is: " << typeid(f_add_display).name() << endl;
}

//--------------test 3----------------
//Foo construct : 200 num_ addr : 001CE934
//copy construct:200 num_ addr : 001CD928
//bbb is : class std::_Binder<struct std::_Unforced, void(__thiscall Foo::*)(int)const, class Foo const &, struct std::_Ph<1> const &>
//Foo destruct: 200 num_ addr : 001CD928
//Foo destruct: 200 num_ addr : 001CE934
void test3()
{
  cout << "--------------test 3----------------" << endl;
  const Foo foo2(200);
  //调用一次拷贝构造函数
  auto bbb =std::bind(&Foo::print_add, foo2, _1); 
  cout << "bbb is: " << typeid(bbb).name() << endl;
}

//--------------test 4----------------
//Foo construct : 300 num_ addr : 001CE934
//copy construct:300 num_ addr : 001CD928
//以下会调用两次拷贝构造函数, 一次是生成临时对象,一次是属于f_add_display2_1
//copy construct:300 num_ addr : 001CC2BC
//copy construct:300 num_ addr : 0069250C
//Foo destruct: 300 num_ addr : 001CC2BC
//sizeof(f_add_display2_1) : 40
//bbb is : class std::_Binder<struct std::_Unforced, void(__thiscall Foo::*)(int)const, class Foo const &, struct std::_Ph<1> const &>
//f_add_display2_1 is : class std::function<void __cdecl(int)>
//Foo destruct: 300 num_ addr : 0069250C
//Foo destruct: 300 num_ addr : 001CD928
//Foo destruct: 300 num_ addr : 001CE934
void test4()
{
  cout << "--------------test 4----------------" << endl;
  //函数对象, 绑定到了Foo类的print_add
  const Foo foo4(300);
  
  //调用一次拷贝构造函数
  auto bbb = std::bind(&Foo::print_add, foo4, _1);
  cout << "以下会调用两次拷贝构造函数, 一次是生成临时对象,一次是属于f_add_display2_1" << endl;
  // store a call to a member function and object
  std::function<void(int)> f_add_display2_1 = bbb;
  cout << "sizeof(f_add_display2_1): " << sizeof(f_add_display2_1) << endl;
  cout << "bbb is: " << typeid(bbb).name() << endl;
  cout << "f_add_display2_1 is: " << typeid(f_add_display2_1).name() << endl;
}

//--------------test 5----------------
//Foo construct : 400 num_ addr : 00AFE9DC
//以下会调用两次拷贝构造函数, 一次是生成临时对象,一次是属于f_add_display2_2
//copy construct:400 num_ addr : 00AFD348
//copy construct:400 num_ addr : 02EFFBAC
//Foo destruct: 400 num_ addr : 00AFD348
//433
//444
//copy construct:400 num_ addr : 02F00D2C
//499
//f_add_display2_2 is : class std::function<void __cdecl(int)>
//hahah is : class std::function<void __cdecl(int)>
//Foo destruct: 400 num_ addr : 02F00D2C
//Foo destruct: 400 num_ addr : 02EFFBAC
//Foo destruct: 400 num_ addr : 00AFE9DC
void test5()
{
  cout << "--------------test 5----------------" << endl;
  const Foo foo5(400);
  // store a call to a member function and object
  cout << "以下会调用两次拷贝构造函数, 一次是生成临时对象,一次是属于f_add_display2_2" << endl;
  std::function<void(int)> f_add_display2_2 = std::bind(&Foo::print_add, foo5, _1);
  f_add_display2_2(33);
  f_add_display2_2(44);
  auto hahah = f_add_display2_2;
  hahah(99);
  cout << "f_add_display2_2 is: " << typeid(f_add_display2_2).name() << endl;
  cout << "hahah is: " << typeid(hahah).name() << endl;
}



//--------------test 6----------------
//Foo construct : 500 num_ addr : 001CE934
//544
//f_add_display3 is : class std::function < void __cdecl(int)>
//555
//f_add_display4 is : class std::function < void __cdecl(int)>
//18
//f_display_obj is : class std::function<void __cdecl(int)>
//Foo destruct: 500 num_ addr : 001CE934
void test6()
{
  cout << "--------------test 6----------------" << endl;
  const Foo foo3(500);
  // store a call to a member function and object ptr, 不会生成一个新的临时对象
  std::function<void(int)> f_add_display3 = std::bind(&Foo::print_add, &foo3, _1);
  f_add_display3(44);
  cout << "f_add_display3 is: " << typeid(f_add_display3).name() << endl;

  std::function<void(int)> f_add_display4 = f_add_display3;
  f_add_display4(55);
  cout << "f_add_display4 is: " << typeid(f_add_display4).name() << endl;

  // store a call to a function object
  std::function<void(int)> f_display_obj = PrintNum();
  f_display_obj(18);
  cout << "f_display_obj is: " << typeid(f_display_obj).name() << endl;
}

//--------------test 7----------------
//Foo construct : 500 num_ addr : 008FEB54
//num_ : 500
//  f_num is : class std::function<int __cdecl(class Foo const &)>
//  Foo destruct: 500 num_ addr : 008FEB54
void test7()
{
  cout << "--------------test 7----------------" << endl;
  const Foo foo3(500);
  // store a call to a data member accessor
  std::function<int(Foo const&)> f_num = &Foo::num_;
  std::cout << "num_: " << f_num(foo3) << '\n';
  cout << "f_num is: " << typeid(f_num).name() << endl;
}
int main() {
  test1();
  test2();
  test3();
  test4();
  test5();
  test6();
  test7();
  system("pause");
  return 0;
}

猜你喜欢

转载自blog.csdn.net/dyingfair/article/details/80299367