bind 是什么?

bind 顾名思义: 绑定

通俗来讲呢,可以这么理解有点像函数指针的意思。

资料上是这么讲的:可以将 bind 函数看做一个通用函数的适配器,它接受一个可调用对象,生成一个新的可以调用对象来“适应”原对象参数列表

它一般调用形式:

// 其中 newCallable 是一个可调用的对象, arg_list 是以逗号分隔的参数列表
// 这时我们调用 newCallable,newCallable 就会调用 callable, 并用 arg_list 传递参数
auto newCallable = bind(callable, arg_list);

好了,重点在于 arg_list 里,那么我们如何传入参数呢

它们是靠这些参数的位置来识别的,形如 _n 之类的, n 是整形, _1 是第一个参数,_2是第二个参数,以此类推。

而名字 _n 是定义在 placeholders 命名空间中, 而 placeholders 本身又定义在 std 命名空间中, 所以形如:

using std:: placeholders::_1

接下来,我们举例几个列子

举个栗子

bind 是在头文件 #include <functional> 中, 首先要包含它。

1. bind 无参数的普通函数

#include <iostream>
#include <functional> // 包含此头文件 // 普通函数
void Fun()
{
std::cout << "I am Fun!" << std::endl;
} // 主函数
int main()
{
auto fun = std::bind(Fun); // 适配 Fun 函数并返回一个可调用的对象
fun();
return 0;
}

调试结果:

2. bind 1个参数的普通函数

#include <iostream>
#include <functional> // 包含此头文件 // 普通函数
void Fun(int a)
{
std::cout << "I am Fun! a = " << a <<std::endl;
} // 主函数
int main()
{
auto fun = std::bind(Fun, std::placeholders::_1);
fun(5);
return 0;
}

调试结果:

3. bind 多个参数的普通函数

#include <iostream>
#include <functional> // 包含此头文件 // 普通函数
int Fun(int a, int b)
{
return a - b;
} // 主函数
int main()
{
auto fun = std::bind(Fun, std::placeholders::_1, std::placeholders::_2);
std::cout << fun(5, 2) << std::endl;
return 0;
}

调试结果:

4. bind 多个参数的普通函数并打乱参数位置

#include <iostream>
#include <functional> // 包含此头文件 // 普通函数
int Fun(int a, int b)
{
return a - b;
} // 主函数
int main()
{
auto fun1 = std::bind(Fun, std::placeholders::_1, std::placeholders::_2);
auto fun2 = std::bind(Fun, std::placeholders::_2, std::placeholders::_1);
std::cout << fun1(5, 2) << std::endl;
std::cout << fun1(5, 2) << std::endl;
return 0;
}

调试结果:

5. bind 类的成员函数

#include <iostream>
#include <functional> // 包含此头文件 class MyClass {
public:
MyClass() {}
~MyClass() {} public:
void printInfo() {
std::cout << "MyClass Info." << std::endl;
}
}; // 主函数
int main()
{
MyClass A;
auto fun = std::bind(&MyClass::printInfo, A);
fun();
return 0;
}

调试结果:

再举个应用栗子

#include <iostream>
#include <functional> // 包含此头文件 typedef std::function<void(int)> CallbackType;
// A 类
class MyClassA {
public:
void regeditCallBack(CallbackType fun)
{ _callback_fun = fun; } void printInfoA(int d)
{ _callback_fun(d); } private:
CallbackType _callback_fun;
};
// B 类
class MyClassB {
public:
void printInfoB(int d) {
std::cout << d << std::endl;
}
}; // 主函数
int main()
{
MyClassB B;
auto funB = std::bind(&MyClassB::printInfoB, B, std::placeholders::_1); MyClassA A;
A.regeditCallBack(funB);
A.printInfoA(1); return 0;
}

调试结果:

结束

学无止境

C++11 标准库 bind 函数的更多相关文章

  1. c/c++ 标准库 bind 函数 详解

    标准库 bind 函数 详解 bind函数:接收一个函数名作为参数,生成一个新的函数. auto newCallable = bind(callbale, arg_list); arg_list中的参 ...

  2. 标准库bind函数中使用占位符placeholders

    placeholders ,占位符.表示新的函数对象中参数的位置.当调用新的函数对象时,新函数对象会调用被调用函数,并且其参数会传递到被调用函数参数列表中持有与新函数对象中位置对应的占位符. 举个例子 ...

  3. C++11 标准库也有坑(time-chrono)

    恰巧今天调试程序遇到时间戳问题, 于是又搜了搜关于取时间戳,以及时间戳转字符串的问题, 因为 time()   只能取到秒(win和linux) 想试试看能不能找到 至少可以取到毫秒的, 于是, 就找 ...

  4. Atitit 数据库 标准库  sdk 函数库 编程语言 mysql oracle  attilax总结

    Atitit 数据库 标准库  sdk 函数库 编程语言 mysql oracle  attilax总结 1.1. 常见的编程语言以及数据库 sql内部函数库标准化库一般有以下api1 1.2. 各个 ...

  5. c++多线程编程:实现标准库accumulate函数的并行计算版本

    今天使用c++实现了标准库头文件<numeric>中的accumulate函数的并行计算版本,代码如下,注释写的比较详细,仅对其中几点进行描述: ①该实现假定不发生任何异常,故没有对可能产 ...

  6. C++11标准库中cstdio头文件新增的5个格式化I/O函数学习

    刚开始学网络编程,稍微扩展书上的简单C/S程序时,发现以前太忽略标准I/O这一块,查官网发现C++11新增了几个格式化I/O函数. snprintf    将格式化输出写入到有大小限制的缓存中 vfs ...

  7. 11. 标准库浏览 – Part II

    第二部分包含了支持专业编程工作所需的更高级的模块,这些模块很少出现在小脚本中. 11.1. 输出格式 reprlib 模块为大型的或深度嵌套的容器缩写显示提供了 :repr() 函数的一个定制版本: ...

  8. C标准库常用函数概要

    stdio.h printf()/fprintf() printf的返回值是打印的字符数, 发生错误则返回负数 scanf()/fscanf() scanf的返回值是成功赋值的变量个数, 失败则返回E ...

  9. 【C++】标准库sort函数的自定义排序

    自定义排序需要单独写一个compare函数 例1 LeetCode 056. Merge Intervals Given a collection of intervals, merge all ov ...

随机推荐

  1. More Effective C++笔记(一)(精心整理)

    一.基础议题 条款1:仔细区别pointers和references 指针使用*和->,引用使用"." 引用必须指向一个已初始化的对象,不能为null,而指针可以指向某个对象 ...

  2. 常用的Dos(Win+R)命令

    打开CMD的方式 开始 + 系统 + 命令提示符 win + R --> 输入CMD 管理员方式运行:开始-->windows系统-->右击命令提示符-->管理员身份运行(最高 ...

  3. 调用企业微信API拨打紧急通知电话

    # 前提条件:企业信息:行业类型必须属于"医疗"大类,客服反馈说目前不支持其他行业# 准备工作:https://work.weixin.qq.com/api/doc/90000/9 ...

  4. Tomcat无法启动解决办法

    [2014-04-12 12:34:39] [error] [ 1080] 操作系统找不到已输入的环境选项. [2014-04-12 12:34:39] [error] [ 1052] Failed ...

  5. [loj3032]馕

    (直接贪心会导致分子和分母过大) 令$S_{i}=\sum_{j=1}^{L}V_{i,j}$(即其独吞整个馕的快乐度),对第$i$个人求出$n$个位置$x_{1},x_{2},...,x_{n-1} ...

  6. Ubuntu文件系统结构

    /bin: bin是Binary的缩写.存放系统中最常用的可执行文件(二进制). /boot: 这里存放的是linux内核和系统启动文件,包括Grub.lilo启动器程序. /dev: dev是Dev ...

  7. idea增加jvm内存

    -server -XX:PermSize=256M -XX:MaxPermSize=1024m

  8. 链式调用Builder

    使用Lombok实现链式调用 1.静态调用 User对象: 对象中必须有一个值不为空staticname作为指定的参数并调用对象 @Accessors(chain = true) @Getter @S ...

  9. Hi3516开发笔记(四):Hi3516虚拟机编译uboot、kernel、roofts和userdata以及分区表

    若该文为原创文章,转载请注明原文出处本文章博客地址:https://hpzwl.blog.csdn.net/article/details/121572767红胖子(红模仿)的博文大全:开发技术集合( ...

  10. Go语言核心36讲(Go语言实战与应用十八)--学习笔记

    40 | io包中的接口和工具 (上) 我们在前几篇文章中,主要讨论了strings.Builder.strings.Reader和bytes.Buffer这三个数据类型. 知识回顾 还记得吗?当时我 ...