C++11中bind绑定器和function函数对象实例分析

这篇文章主要介绍了C++11中bind绑定器和function函数对象实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++11中bind绑定器和function函数对象实例分析文章都

这篇文章主要介绍了C++11中bind绑定器和function函数对象实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++11中bind绑定器和function函数对象实例分析文章都会有所收获,下面我们一起来看看吧。

一. bind1st和bind2nd

1.C++ STL中的绑定器

  • bind1st:operator()的第一个形参变量绑定成一个确定的值

  • bind2nd:operator()的第二个形参变量绑定成一个确定的值

C++11从Boost库中引入了bind绑定器和function函数对象机制

bind可用于给多元函数降元:Bind + 二元函数对象 = 一元函数对象

  1. #include<iostream>
  2. #include<vector>
  3. #include<functional>
  4. #include<algorithm>//泛型算法
  5. #include<ctime>
  6. using namespace std;
  7. template<typename Container>
  8. void showContainer(Container& con)
  9. {
  10. //typename Container::iterator it=con.begin();
  11. auto it = con.begin();
  12. for (; it != con.end(); ++it)
  13. {
  14. cout << *it << " ";
  15. }
  16. cout << endl;
  17. }
  18. int main()
  19. {
  20. vector<int> vec;
  21. srand(time(nullptr));
  22. for (int i = 0; i < 20; ++i)
  23. {
  24. vec.push_back(rand() % 100 + 1);
  25. }
  26. showContainer(vec);
  27.  
  28. sort(vec.begin(), vec.end());//默认从小到大排序
  29. showContainer(vec);
  30.  
  31. //greater需要二元函数对象
  32. sort(vec.begin(), vec.end(), greater<int>());//从大到小排序
  33. showContainer(vec);
  34.  
  35. /*
  36. 把70按顺序插入到vec容器中 ->找第一个小于70的数字
  37. operator()(const T &val)
  38. greater a>b
  39. less a<b
  40. 绑定器+二元函数对象=》一元函数对象
  41. bind1st:+greater bool operator()(70,const_Ty&_Right)
  42. bind2nd:+less bool operator()(const_Ty &_Left,70)
  43. */
  44. auto it1 = find_if(vec.begin(), vec.end(), bind1st(greater<int>(), 70));
  45. if (it1 != vec.end())
  46. {
  47. vec.insert(it1, 70);
  48. }
  49. showContainer(vec);
  50. return 0;
  51. }

2.bind1st和bind2nd的底层原理实现

绑定器本身是一个函数对象

  1. #include<iostream>
  2. #include<vector>
  3. #include<functional>
  4. #include<algorithm>
  5. #include<ctime>
  6. using namespace std;
  7. template<typename Container>
  8. void showContainer(Container& con)
  9. {
  10. auto it = con.begin();
  11. for (; it != con.end(); ++it)
  12. {
  13. cout << *it << " ";
  14. }
  15. cout << endl;
  16. }
  17. //遍历两个迭代器之间的元素,如果满足函数对象的运算,就返回当前的迭代器,如果都不满足就返回end
  18. template<typename Iterator,typename Compare>
  19. Iterator my_find_if(Iterator first, Iterator last, Compare comp)
  20. {
  21. //这里传入的comp是封装好的一元函数对象
  22. for (; first != last; ++first)
  23. {
  24. if (comp(*first))//获取容器的一个元素
  25. {
  26. return first;
  27. }
  28. }
  29. return last;
  30. }
  31. template<typename Compare,typename T>
  32. class _mybind1st//绑定器是函数对象的一个应用
  33. {
  34. public:
  35. //这里传入的comp是二元函数对象
  36. _mybind1st(Compare comp,T val)
  37. :_comp(comp),_val(val){}
  38. //通过重载operator()把二元函数对象封装为一元函数对象
  39. bool operator()(const T& second)
  40. {
  41. return _comp(_val, second);
  42. }
  43. private:
  44. Compare _comp;
  45. T _val;
  46. };
  47. template<typename Compare,typename T>
  48. _mybind1st<Compare, T> mybind1st(Compare comp, const T& val)
  49. {
  50. //直接使用函数模板,好处是可以进行类型的推演
  51. //这里传入的comp是一个二元函数对象
  52. //通过二元函数对象构造一元函数对象
  53. //绑定器本身是一个函数对象,也就是重载了operator()
  54. return _mybind1st<Compare, T>(comp, val);
  55. }
  56. int main()
  57. {
  58. vector<int> vec;
  59. srand(time(nullptr));
  60. for (int i = 0; i < 20; ++i)
  61. {
  62. vec.push_back(rand() % 100 + 1);
  63. }
  64. showContainer(vec);
  65.  
  66. sort(vec.begin(), vec.end());//默认从小到大排序
  67. showContainer(vec);
  68.  
  69. //greater需要二元函数对象
  70. sort(vec.begin(), vec.end(), greater<int>());//从大到小排序
  71. showContainer(vec);
  72.  
  73. auto it1 = my_find_if(vec.begin(), vec.end(), mybind1st(greater<int>(), 70));
  74. if (it1 != vec.end())
  75. {
  76. vec.insert(it1, 70);
  77. }
  78. showContainer(vec);
  79.  
  80. return 0;
  81. }

二. 模板的完全特例化和非完全特例化

有完全特例化优先匹配完全特例化,有部分特例化就匹配部分特例化,没有的话就从原模板自己实例化

  1. #include<iostream>
  2. using namespace std;
  3. template<typename T>
  4. class Vector
  5. {
  6. public:
  7. Vector() { cout << "call Vector template init" << endl; }
  8. };
  9. //对char*类型提供完全特例化版本
  10. template<>
  11. class Vector<char*>
  12. {
  13. public:
  14. Vector() { cout << "call Vector<char*> init" << endl; }
  15. };
  16. //对指针类型提供的部分特例化版本(部分:只知道是个指针,但是指针的类型是什么不知道)
  17. template<typename Ty>
  18. class Vector<Ty*>
  19. {
  20. public:
  21. Vector() { cout << "call Vector<Ty*> init" << endl; }
  22. };
  23. //指针函数指针(有返回值,有两个形参变量)提供的部分特例化
  24. template<typename R,typename A1,typename A2>
  25. class Vector<R(*)(A1, A2)>
  26. {
  27. public:
  28. Vector() { cout << "call Vector<R(*)(A1,A2)> init" << endl; }
  29. };
  30. //针对函数(有一个返回值,有两个形参变量)类型提供的部分特例化
  31. template<typename R, typename A1, typename A2>
  32. class Vector<R(A1, A2)>
  33. {
  34. public:
  35. Vector() { cout << "call Vector<R(A1,A2)> init" << endl; }
  36. };
  37. int sum(int a, int b) { return a + b; }
  38. int main()
  39. {
  40. Vector<int> vec1;
  41. Vector<char*> vec2;
  42. Vector<int*> vec3;
  43. Vector<int(*)(int, int)> vec4;
  44. Vector<int(int, int)> vec5;
  45.  
  46. //注意区分函数类型和函数指针类型
  47. typedef int(*PFUNC1)(int, int);
  48. PFUNC1 pfunc1 = sum;
  49. cout << pfunc1(10, 20) << endl;
  50.  
  51. typedef int PFUNC2(int, int);
  52. PFUNC2* pfunc2 = sum;
  53. cout << (*pfunc2)(10, 20) << endl;
  54. return 0;
  55. }

C++11中bind绑定器和function函数对象实例分析

  1. #include<iostream>
  2. #include<typeinfo>
  3. using namespace std;
  4. //T包含了所有大的类型
  5. template<typename T>
  6. void func(T a)
  7. {
  8. cout << typeid(T).name() << endl;
  9. }
  10. int sum(int a, int b) { return a + b; }
  11.  
  12. //把所有形参类型都取出来
  13. template<typename R, typename A1, typename A2>
  14. void func2(R(*a)(A1, A2))
  15. {
  16. cout << typeid(R).name() << endl;
  17. cout << typeid(A1).name() << endl;
  18. cout << typeid(A2).name() << endl;
  19. }
  20. template<typename R,typename T,typename A1,typename A2>
  21. void func3(R(T::*a)(A1, A2))
  22. {
  23. cout << typeid(R).name() << endl;
  24. cout << typeid(T).name() << endl;
  25. cout << typeid(A1).name() << endl;
  26. cout << typeid(A2).name() << endl;
  27. }
  28. class Test
  29. {
  30. public:
  31. int sum(int a, int b) { return a + b; }
  32. };
  33. int main()
  34. {
  35. //func(10);//int
  36. //func("aaa");//const char *
  37. func(sum);
  38. func2(sum);
  39. func3(&Test::sum);
  40. return 0;
  41. }

C++11中bind绑定器和function函数对象实例分析

三. function函数对象

绑定器,函数对象,lambda表达式本质上都是函数对象,只能使用在一条语句中,但是如果想要在多条语句中使用,就需要function

使用function函数需要注意:

  • 函数类型实例化function;

  • 通过function调用operator()函数的时候,需要根据函数类型传入相应的参数

  1. #include<iostream>
  2. #include<functional>
  3. using namespace std;
  4. void hello1()
  5. {
  6. cout << "hello world!" << endl;
  7. }
  8. void hello2(string str)
  9. {
  10. cout << str << endl;
  11. }
  12. int sum(int a, int b)
  13. {
  14. return a + b;
  15. }
  16. int main()
  17. {
  18. //从function的模板定义处,看到希望用一个函数类型实例化function
  19. function<void()> func1 = hello1;
  20. func1();//func1.operator() => hello1()
  21.  
  22. function<void(string)> func2 = hello2;
  23. func2("hello hello2!");
  24.  
  25. function<int(int, int)> func3 = sum;
  26. cout << func3(2, 3) << endl;
  27.  
  28. function<int(int, int)> func4 = [](int a, int b)->int {return a + b; };
  29. cout << func4(3, 4) << endl;
  30. return 0;
  31. }

C++11中bind绑定器和function函数对象实例分析

function不仅可以留下普通全局函数的类型,对于类的成员方法也可以进行类型保留:

  1. #include<iostream>
  2. #include<functional>
  3. using namespace std;
  4.  
  5. class Test
  6. {
  7. public://必须依赖一个对象void(Test::*pfunc)(string)
  8. void hello(string str) { cout << str << endl; }
  9. };
  10. int main()
  11. {
  12. //成员方法一经编译都会多一个当前类型的this指针
  13. function<void (Test*, string)> func = &Test::hello;
  14. Test t;
  15. //对于成员方法的调用需要依赖一个成员对象
  16. func(&t, "call Test::hello!");
  17. return 0;
  18. }

function的特点:可以把所有函数、绑定器、函数对象和lambda表达式的类型保留起来,在其他地方都可以使用。否则绑定器、lambda表达式就只能使用在语句中。

  1. #include<iostream>
  2. #include<functional>
  3. #include<map>
  4. using namespace std;
  5. void doShowAllBooks(){ cout << "查看所有书籍信息" << endl; }
  6. void doBorrow() { cout << "借书" << endl; }
  7. void doBack() { cout << "还书" << endl; }
  8. void doQueryBooks() { cout << "查询书籍" << endl; }
  9. void doLoginOut() { cout << "注销" << endl; }
  10. int main()
  11. {
  12. int choice = 0;
  13. //使用function函数对象完成
  14. map<int, function<void()>> actionMap;
  15. actionMap.insert({ 1,doShowAllBooks });
  16. actionMap.insert({ 2,doBorrow });
  17. actionMap.insert({ 3,doBack });
  18. actionMap.insert({ 4,doQueryBooks });
  19. actionMap.insert({ 5,doLoginOut });
  20. for (;;)
  21. {
  22. cout << "------------------" << endl;
  23. cout << "1.查看所有书籍信息" << endl;
  24. cout << "2.借书" << endl;
  25. cout << "3.还书" << endl;
  26. cout << "4.查询书籍" << endl;
  27. cout << "5.注销" << endl;
  28. cout << "------------------" << endl;
  29. cout << "请选择:";
  30. cin >> choice;
  31.  
  32. auto it = actionMap.find(choice);
  33. if (it == actionMap.end())
  34. {
  35. cout << "输入数字无效,重新选择" << endl;
  36. }
  37. else
  38. {
  39. it->second();
  40. }
  41. //不好,因为这块代码无法闭合,无法做到“开-闭”原则,也就是说这块代码随着需求的更改需要一直改,永远也闭合不了,避免不了要产生很多问题
  42. /*
  43. switch(choice)
  44. {
  45. case 1:break;
  46. case 2:break;
  47. case 3:break;
  48. case 4:break;
  49. case 5:break;
  50. default:break;
  51. }
  52. */
  53. }
  54. return 0;
  55. }

function的实现原理:

  1. #include<iostream>
  2. #include<functional>
  3. using namespace std;
  4.  
  5. void hello(string str) { cout << str << endl; }
  6. int sum(int a, int b) { return a + b; }
  7.  
  8. template<typename Fty>
  9. class myfunction{};
  10. /*
  11. template<typename R,typename A1>
  12. class myfunction<R(A1)>
  13. {
  14. public:
  15. //typedef R(*PFUNC)(A1);
  16. using PFUNC = R(*)(A1);
  17. myfunction(PFUNC pfunc):_pfunc(pfunc){}
  18. R operator()(A1 arg)
  19. {
  20. return _pfunc(arg);
  21. }
  22. private:
  23. PFUNC _pfunc;
  24. };
  25.  
  26. template<typename R, typename A1,typename A2>
  27. class myfunction<R(A1,A2)>
  28. {
  29. public:
  30. //typedef R(*PFUNC)(A1);
  31. using PFUNC = R(*)(A1,A2);
  32. myfunction(PFUNC pfunc) :_pfunc(pfunc) {}
  33. R operator()(A1 arg1,A2 arg2)
  34. {
  35. return _pfunc(arg1,arg2);
  36. }
  37. private:
  38. PFUNC _pfunc;
  39. };
  40. */
  41. //...表示可变参,A表示的是一组1类型,个数任意
  42. template<typename R, typename... A>
  43. class myfunction<R(A...)>
  44. {
  45. public:
  46. using PFUNC = R(*)(A...);
  47. myfunction(PFUNC pfunc) :_pfunc(pfunc) {}
  48. operator()(A... arg)
  49. {
  50. return _pfunc(arg...);
  51. }
  52. private:
  53. PFUNC _pfunc;
  54. };
  55. int main()
  56. {
  57. myfunction<void(string)> func1(hello);
  58. func1("hello world");
  59. myfunction<int(int, int)> func2(sum);
  60. cout << func2(10, 20) << endl;
  61. return 0;
  62. }

四. bind和function实现线程池

  1. #include<iostream>
  2. #include<functional>
  3. using namespace std;
  4. using namespace placeholders;
  5.  
  6.  
  7. //C++11 bind 绑定器=>返回的结果是一个函数对象
  8. void hello(string str) { cout << str << endl; }
  9. int sum(int a, int b) { return a + b; }
  10. class Test
  11. {
  12. public:
  13. int sum(int a, int b) { return a + b; }
  14. };
  15.  
  16. int main()
  17. {
  18. //bind是函数模板,可以自动推演模板类型参数
  19. bind(hello, "Hello bind!")();
  20. cout << bind(sum, 20, 30)() << endl;
  21. cout << bind(&Test::sum, Test(), 20, 30)() << endl;
  22. //function只接受一个类型,绑定器可以给相应的函数绑定固定的参数,绑定器只能使用在语句当中
  23. //参数占位符,绑定器出了语句,无法继续使用
  24. bind(hello, _1)("hello bind 2");
  25. cout << bind(sum, _1, _2)(20, 30) << endl;
  26. //此处把bind返回的绑定器binder就复用起来了
  27. function<void(string)> func1 = bind(hello, _1);
  28. func1("hello china!");
  29. func1("hello shan xi!");
  30. func1("hello da li!");
  31.  
  32. }
  1. #include<iostream>
  2. #include<functional>
  3. #include<thread>
  4. #include<vector>
  5. using namespace std;
  6. using namespace placeholders;
  7.  
  8. //线程类
  9. class Thread
  10. {
  11. public:
  12. Thread(function<void(int)> func,int no):_func(func),_no(no){}
  13. thread start()
  14. {
  15. thread t(_func,_no);
  16. return t;
  17. }
  18. private:
  19. function<void(int)> _func;
  20. int _no;
  21. };
  22. //线程池类
  23. class ThreadPool
  24. {
  25. public:
  26. ThreadPool(){}
  27. ~ThreadPool()
  28. {
  29. //释放thread对象占用的堆资源
  30. for (int i = 0; i < _pool.size(); i++)
  31. {
  32. delete _pool[i];
  33. }
  34. }
  35. //开启线程池
  36. void startPool(int size)
  37. {
  38. for (int i = 0; i < size; i++)
  39. {
  40. //不管是C++里面的thread还是Linux里面的pthread需要的线程函数都是一个C函数,是不能够使用成员方法的,因为它是C的函数类型,不可能把成员方法的函数指针给一个C的函数指针,接收不了。所以就需要绑定,把runInThread所依赖的参数全部绑定
  41. _pool.push_back(new Thread(bind(&ThreadPool::runInThread, this, _1),i));
  42. }
  43. for (int i = 0; i < size; i++)
  44. {
  45. _handler.push_back(_pool[i]->start());
  46. }
  47. for (thread& t : _handler)
  48. {
  49. t.join();
  50. }
  51. }
  52. private:
  53. vector<Thread*> _pool;
  54. vector<thread> _handler;
  55. //把runInThread这个成员方法充当线程函数
  56. void runInThread(int id)
  57. {
  58. cout << "call runInThread! id:" << id << endl;
  59. }
  60. };
  61. int main()
  62. {
  63. ThreadPool pool;
  64. pool.startPool(10);
  65. return 0;
  66. }

五. lambda表达式

  • 函数对象的应用:使用在泛型算法参数传递、比较性质、自定义操作、优先级队列和智能指针

  • 函数对象的缺点:需要先定义一个函数对象类型,但是类型定义完后可能只是用在了定义的地方,后面可能不会再用了,没有必要为了需要一个函数对象定义一个类型,这个类型就永远在代码当中。

C++11函数对象的升级版 => lambda表达式:

  • lambda表达式:底层依赖函数对象的机制实现的

  • lambda表达式语法:[捕获外部变量](形参列表) ->返回值{操作代码};

如果lambda表达式的返回值不需要,那么“->返回值”可以省略

[捕获外部变量]

  • [ ]:表示不捕获任何外部变量

  • [=]:以传值的方式捕获外部的所有变量

  • [&]:以传引用的方式捕获外部的所有变量[this]:捕获外部的this指针

  • [=,&a]:以传值的方式捕获外部的所有变量,但是a变量以传引用的方式捕获

  • [a,b]:以传值的方式捕获外部变量a和b

  • [a,&b]:a以值传递捕获,b以传引用的方式捕获

1.lambda表达式的实现原理

  1. #include<iostream>
  2. using namespace std;
  3. template<typename T=void>
  4. class TestLambda01
  5. {
  6. public:
  7. void operator()()
  8. {
  9. cout << "hello world" << endl;
  10. }
  11. };
  12. template<typename T = int>
  13. class TestLambda02
  14. {
  15. public:
  16. TestLambda02() {}
  17. int operator()(int a, int b)
  18. {
  19. return a + b;
  20. }
  21. };
  22. template<typename T = int>
  23. class TestLambda03
  24. {
  25. public:
  26. TestLambda03(int a,int b):ma(a),mb(b){}
  27. void operator()()const
  28. {
  29. int tmp = ma;
  30. ma = mb;
  31. mb = tmp;
  32. }
  33. private:
  34. mutable int ma;
  35. mutable int mb;
  36. };
  37. class TestLambda04
  38. {
  39. public:
  40. TestLambda04(int &a,int &b):ma(a),mb(b){}
  41. void operator()()const
  42. {
  43. int tmp = ma;
  44. ma = mb;
  45. mb = tmp;
  46. }
  47. private:
  48. int& ma;
  49. int& mb;
  50. };
  51. int main()
  52. {
  53. auto func1 = []()->void {cout << "hello world" << endl; };
  54. func1();
  55.  
  56. auto func2 = [](int a, int b)->int {return a + b; };
  57. cout << func2(20, 30) << endl;
  58.  
  59. int a = 10;
  60. int b = 20;
  61. //按值传递a,b值未被改变
  62. auto func3 = [a, b]()mutable
  63. {
  64. int tmp = a;
  65. = b;
  66. = tmp;
  67. };
  68. func3();
  69. cout << "a:" << a << " b:" << b << endl;
  70. //传引用值a,b值被改变
  71. auto func4 = [&]()
  72. {
  73. int tmp = a;
  74. = b;
  75. = tmp;
  76. };
  77. func4();
  78. cout << "a:" << a << " b:" << b << endl;
  79.  
  80. cout << "--------------------" << endl;
  81. TestLambda01<> t1;
  82. t1();
  83. TestLambda02<> t2;
  84. cout << t2(20, 30) << endl;
  85. TestLambda03<> t3(a,b);
  86. t3();
  87. cout << "a:" << a << " b:" << b << endl;
  88. TestLambda04 t4(a,b);
  89. t4();
  90. cout << "a:" << a << " b:" << b << endl;
  91. return 0;
  92. }

C++11中bind绑定器和function函数对象实例分析

mutable:成员变量本身也不是常量,只不过在常方法中this指针被修饰成const,在声明成员变量前加mutable,可以在const方法中修改普通的成员变量

lambda表达式后面修饰mutable相当于在它的所有成员变量添加一个mutable修饰。

2.lambda表达式的应用实践

lambda表达式应用于泛型算法:

  1. #include<iostream>
  2. #include<vector>
  3. #include<algorithm>
  4. using namespace std;
  5.  
  6. int main()
  7. {
  8. vector<int> vec;
  9. for (int i = 0; i < 20; ++i)
  10. {
  11. vec.push_back(rand() % 100 + 1);
  12. }
  13. sort(vec.begin(), vec.end(),
  14. [](int a, int b)->bool
  15. {
  16. return a > b;
  17. });
  18. for (int val : vec)
  19. {
  20. cout << val << " ";
  21. }
  22. cout << endl;
  23. //65按序插入序列 要找一个小于65的数字
  24. auto it = find_if(vec.begin(), vec.end(),
  25. [](int a)->bool {return a < 65; });
  26. if (it != vec.end())
  27. {
  28. vec.insert(it, 65);
  29. }
  30. for (int val : vec)
  31. {
  32. cout << val << " ";
  33. }
  34. cout << endl;
  35. for_each(vec.begin(), vec.end(), [](int a)
  36. {
  37. if (% 2 == 0)
  38. cout << a << " ";
  39. });
  40. cout << endl;
  41. return 0;
  42. }

既然lambda表达式只能使用在语句中,如果想跨语句使用之前定义好的lambda表达式,采用function类型来表示函数对象的类型。

哈希表的应用:

  1. #include<iostream>
  2. #include<vector>
  3. #include<map>
  4. #include<functional>
  5. using namespace std;
  6. int main()
  7. {
  8. //auto只能出现在根据右边表达式推导左边的类型,只能使用在函数的局部作用域的范围之内
  9. //预先lambda表达式不知道需要先存储lambda表达式类型
  10. map<int, function<int(int, int)>> caculateMap;
  11. caculateMap[1] = [](int a, int b)->int {return a + b; };
  12. caculateMap[2] = [](int a, int b)->int {return a - b; };
  13. caculateMap[3] = [](int a, int b)->int {return a * b; };
  14. caculateMap[4] = [](int a, int b)->int {return a / b; };
  15.  
  16. cout << "请选择";
  17. int choice;
  18. cin >> choice;
  19. cout << caculateMap[choice](10, 15) << endl;
  20. return 0;
  21. }

智能指针自定义删除器:

  1. #include<iostream>
  2. #include<vector>
  3. #include<functional>
  4. using namespace std;
  5. int main()
  6. {
  7. unique_ptr<FILE, function<void(FILE*)>>
  8. ptr1(fopen("data.txt", "w"), [](FILE* pf) {fclose(pf); });
  9. }

传入函数对象使得容器元素按照指定方式排列:

  1. #include<iostream>
  2. #include<vector>
  3. #include<functional>
  4. #include <queue>
  5. using namespace std;
  6.  
  7. class Data
  8. {
  9. public:
  10. Data(int val1=10,int val2=10):ma(val1),mb(val2){}
  11. int ma;
  12. int mb;
  13. };
  14. int main()
  15. {
  16. //优先级队列
  17. //priority_queue<Data> queue;
  18. using FUNC = function<bool(Data&, Data&)>;
  19. priority_queue<Data, vector<Data>, FUNC>
  20. maxHeap([](Data& d1, Data& d2)->bool
  21. {
  22. return d1.mb > d2.mb;
  23. });
  24. maxHeap.push(Data(10, 20));
  25. maxHeap.push(Data(15, 15));
  26. maxHeap.push(Data(20, 10));
  27. }

关于“C++11中bind绑定器和function函数对象实例分析”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“C++11中bind绑定器和function函数对象实例分析”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注恰卡网行业资讯频道。

本站部分文章来自网络或用户投稿,如无特殊说明或标注,均为本站原创发布。涉及资源下载的,本站旨在共享仅供大家学习与参考,如您想商用请获取官网版权,如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
后端

Django怎么上传excel表格并将数据写入数据库

2022-7-16 21:35:24

后端

JS前端千万级弹幕数据循环优化的方法

2022-7-16 21:37:57

搜索