c++ bind函数与function函数简介及使用方法

一.bind函数

       1.简介:

  std::bind将一个callable object与其参数绑定在一起,并生成一个新的callable object。通俗的讲,bind可以使函数先获得一部分参数,把函数包装起来,在需要调用函数的时候把剩余的参数补全即可。

   用途:bind可以提高函数的通用性,可以使多个不同函数通过绑定参数,变成参数列表相同的函数,对于多态,回调函数的实现有巨大的作用,提高了代码的抽象程度。

        2.使用方法:

        bind共可以绑定四种函数,分别为 普通函数,类成员函数,类静态函数,lambda表达式,下面将详细介绍四种函数的使用方法。

        bind不会对函数的返回值做出改变,bind封装后的函数依旧可以获得返回值。

        (1).绑定普通函数

        无参:定义一个普通全局函数,bind的参数填入函数名,即可完成最简单的bind函数绑定。通常bind与auto关键字同时使用。被绑定后的函数变为bind对象,可以通过()直接调用。和调用普通函数一样。

#include<functional>
#include<iostream>
using namespace std;
void tes()
{
	cout << "tes" << endl;
}

int main()
{
	auto ite = std::bind(tes);
	ite();
	return 0;
}

               运行结果如图所示:

       有参:对于有参数的函数,可以选择绑定哪些参数,参数的顺序需要顺序连续,若是有的参数不需要绑定,就要使用 std::placeholders::_1 占位标识符。

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

void tes(int a,int b,int c,int d)
{
	cout << "tes"<< "a :" << a << " b : " << b << " c :" << c << " d : " << d << endl;
}


int main()
{
	myclass c;
	auto ite = std::bind(tes,100, placeholders::_1, 300, placeholders::_2);
	ite(200,400);
	return 0;
}

 运行结果如图所示:

        代码中定义了一个函数test,有四个成员参数,在绑定的时候这四个参数都得出现,要么给传入提供给函数的需要绑定的参数,要么使用占位符。


        对于占位符的使用上,需要注意占位符你的每一个占位符对应后面函数的一个输入参数,如_1对应第一个参数,_2对应第二个参数,所以在使用占位符时数字不能大于后面需要传参的个数。

        在调用bind绑定的函数时,会根据占位符传参,若是占位符是_4,则对应位置传入是第四个参数。所以可以通过对于合理使用占位符,改变参数位置。

        如下:

auto ite = std::bind(tes,placeholders::_4, placeholders::_3, placeholders::_4, placeholders::_4);
ite(100,200,300,400);
auto ite2 = std::bind(tes, 100, placeholders::_2, 300, placeholders::_1);
ite2(200, 400);

运行结果如下:

        对于第一个bind函数,我们第一个占位符为_4,所以传入函数的参数为输入的第四个参数,a为400,第二个占位符为_3,所以传入函数的参数为输入的第三个参数,b为300,后面两个与第一个类似。

        对于第二个bind函数,我们第一个占位符为_2,所以传入函数的参数为输入参数的二个参数,a为400,第二个占位符为_1,所以传入函数的参数为输入的第一个参数,b为200。

        其他函数的参数绑定,与普通函数的参数绑定是一样的,就不再赘述。

        (2).绑定类成员函数

        bind还可以绑定类的成员函数,此时bind至少需要两个参数,第一个参数为类的成员函数(需要通过    &类名::成员函数   的方式填入参数,第二个参数为类对象或者类对象的this指针,对象地址也可。

#include<functional>
#include<iostream>
using namespace std;
class myclass
{
public:
	void myclass_test()
	{
		cout << "myclass_test" << endl;
	}
};
int main()
{
	myclass c;
	auto ite = std::bind(&myclass::myclass_test,c);
	ite();
	return 0;
}

运行如图所示:

        (3).绑定类静态函数

        对于类的静态函数就不用传递第二个参数了,直接通过    &类名::成员函数   的方式填入第一个参数即可。

        绑定lamda表达式

        还可以由lambda表达式作为第一个参数

#include<functional>
#include<iostream>
using namespace std;
class myclass
{
public:
	static void myclass_test()
	{
		cout << "myclass_test" << endl;
	}
};
int main()
{
	myclass c;
	auto ite = std::bind([]() {cout << " lamda" << endl; });
	ite();
	return 0;
}

运行结果如图: 

        

3.参数相关的问题:

        (1).传递参数存在的问题:

        传参过程中需要注意的是参数的传递在bind总是会以复制的方式传递,任何参数被bind绑定时都会被复制一份,然后传递给bind绑定的函数。尽管绑定的函数要的是引用他也是传递他已经复制了的一份。

        (2)解决方式:

        这个问题可以通过ref()函数和cref()函数解决。当遇到需要绑定引用参数的函数时,则把对以后给变量用ref修饰,若需要的时const类型的引用则用cref修饰。

        

        

  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值