• C++ 可调用对象绑定器bind()


    bind1st() 和 bind2nd(),在 C++11 里已经  deprecated 了,建议使用新标准的 bind()

    头文件

    #include <functional>

    bind1st()bind2nd()都是把二元函数转化为一元函数,方法是绑定其中一个参数。
    bind1st()是绑定第一个参数。
    bind2nd()是绑定第二个参数。

    例子:

    1. #include <iostream>
    2. #include <algorithm>
    3. #include <functional>
    4. using namespace std;
    5. int main()
    6. {
    7. int numbers[] = { 10,20,30,40,50,10 };
    8. int cx;
    9. cx = count_if(numbers, numbers + 6, bind2nd(less<int>(), 40));
    10. cout << "There are " << cx << " elements that are less than 40.\n";
    11. cx = count_if(numbers, numbers + 6, bind1st(less<int>(), 40));
    12. cout << "There are " << cx << " elements that are not less than 40.\n";
    13. system("pause");
    14. return 0;
    15. }

    结果:
    There are 4 elements that are less than 40.
    There are 1 elements that are not less than 40.

    bind()

    std::bind用来将可调用对象与其参数一起进行绑定。绑定后的结果可以使用std::function进行保存,并延迟调用到任何我们需要的时候。通俗来讲,它主要有两大作用:

    • 将可调用对象与其参数一起绑定成一个仿函数。
    • 将多元(参数个数为n,n>1)可调用对象转换为一元或者(n-1)元可调用对象,即只绑定部分参数。

    绑定器函数使用语法格式如下:

    // 绑定非类成员函数/变量
    auto f = std::bind(可调用对象地址, 绑定的参数/占位符);
    // 绑定类成员函/变量
    auto f = std::bind(类函数/成员地址, 类实例对象地址, 绑定的参数/占位符);

     下面来看一个关于绑定器的实际使用的例子:

    1. #include <iostream>
    2. #include <functional>
    3. using namespace std;
    4. void callFunc(int x, const function<void(int)>& f)
    5. {
    6. if (x % 2 == 0)
    7. {
    8. f(x);
    9. }
    10. }
    11. void output(int x)
    12. {
    13. cout << x << " ";
    14. }
    15. void output_add(int x)
    16. {
    17. cout << x + 10 << " ";
    18. }
    19. int main(void)
    20. {
    21. // 使用绑定器绑定可调用对象和参数
    22. auto f1 = bind(output, placeholders::_1);
    23. for (int i = 0; i < 10; ++i)
    24. {
    25. callFunc(i, f1);
    26. }
    27. cout << endl;
    28. auto f2 = bind(output_add, placeholders::_1);
    29. for (int i = 0; i < 10; ++i)
    30. {
    31. callFunc(i, f2);
    32. }
    33. cout << endl;
    34. return 0;
    35. }

    结果:

     0  2  4  6  8
    10 12 14 16 18

    在上面的程序中,使用了 std::bind 绑定器,在函数外部通过绑定不同的函数,控制了最后执行的结果。std::bind绑定器返回的是一个仿函数类型,得到的返回值可以直接赋值给一个std::function,在使用的时候我们并不需要关心绑定器的返回值类型,使用auto进行自动类型推导就可以了。

    placeholders::_1 是一个占位符,代表这个位置将在函数调用时被传入的第一个参数所替代。同样还有其他的占位符 placeholders::_2、placeholders::_3、placeholders::_4、placeholders::_5 等……

    有了占位符的概念之后,使得 std::bind 的使用变得非常灵活:

    1. #include <iostream>
    2. #include <functional>
    3. using namespace std;
    4. void output(int x, int y)
    5. {
    6. cout << x << " " << y << endl;
    7. }
    8. int main(void)
    9. {
    10. // 使用绑定器绑定可调用对象和参数, 并调用得到的仿函数
    11. bind(output, 1, 2)();
    12. bind(output, placeholders::_1, 2)(10);
    13. bind(output, 2, placeholders::_1)(10);
    14. // error, 调用时没有第二个参数
    15. // bind(output, 2, placeholders::_2)(10);
    16. // 调用时第一个参数10被吞掉了,没有被使用
    17. bind(output, 2, placeholders::_2)(10, 20);
    18. bind(output, placeholders::_1, placeholders::_2)(10, 20);
    19. bind(output, placeholders::_2, placeholders::_1)(10, 20);
    20. return 0;
    21. }

    示例代码执行的结果:

    1  2        // bind(output, 1, 2)();
    10 2        // bind(output, placeholders::_1, 2)(10);
    2 10        // bind(output, 2, placeholders::_1)(10);
    2 20        // bind(output, 2, placeholders::_2)(10, 20);
    10 20        // bind(output, placeholders::_1, placeholders::_2)(10, 20);
    20 10        // bind(output, placeholders::_2, placeholders::_1)(10, 20);

    通过测试可以看到,std::bind 可以直接绑定函数的所有参数,也可以仅绑定部分参数。在绑定部分参数的时候,通过使用 std::placeholders 来决定空位参数将会属于调用发生时的第几个参数。

     

  • 相关阅读:
    Java集成Onlyoffice以及安装和使用示例,轻松实现word、ppt、excel在线编辑功能协同操作,Docker安装Onlyoffice
    halcon使用算子记录
    小米、Vivo、Oppo后台弹出界面权限检测
    又拍云 Redis 的改进之路
    基于SpringBoot的线上买菜系统
    常见遍历方法 for循环、forEach、map、filter、find、findIndex、some、every
    【学习笔记】内存的连续分配管理方式
    数据结构学习笔记——选择排序(简单选择排序和堆排序)
    【科学文献计量】metaknowledge创建和处理知识网络的方法与 RC.networkCoAuthor()中的参数解释
    理解和熟悉递归中的尝试
  • 原文地址:https://blog.csdn.net/qq_46284579/article/details/125457215