27 新型适配器bind的使用方法

1、概述

上一篇已经介绍G2.9中的能进行参数绑定的适配器bind2nd(绑定第二参数),当然也有绑定第一参数(bind1nd)。而在新版的编译器中有一个新型的绑定适配器bind,下面主要用示例进行介绍其用法。

2、bind的使用方法示例

1)头文件数据

#include <iostream>
using namespace std;
#include <functional>
using namespace std::placeholders;
#include <vector>
#include <algorithm>


double my_divide(double x, double y){
	return x / y;
}//#1

struct MyPair
{
	double a, b;
	double multiply(){ return a*b; }
};//#2
解析:

a、在使用bind()用法前,先在头文件先引出functional,然后预先声明std::placeholders,它的作用是进行占位(符号:_1,_2),具体解释见下例子。

b、因std::bind可以绑定:functions(一般函数)、function objects(仿函数)、member_functions(成员函数)和data_members(类成员)。故声明了#1和#2一个函数和一个类,类中有类数据和类成员函数。#1作用是除法,#2作用是乘法。

2)主程序测试

int _tmain(int argc, _TCHAR* argv[])
{
	auto fn_five = bind(my_divide, 10, 2); //#3 return 10 / 2 
	cout << fn_five() << endl; //5

	auto fn_half = bind(my_divide, _1, 2); //#4 return 10 / 2 
	cout << fn_half(10) << endl; //5

	auto fn_invert = bind(my_divide, _2, _1); //#5 return 2 / 10
	cout << fn_invert(10, 2) << endl; //0.2

	auto fn_rounding = bind<int>(my_divide, _1, _2); //#6 return int(10 / 3)
	cout << fn_rounding(10, 3) << endl; //3

	//binding member
	MyPair ten_two{ 10, 2 };

	auto bound_memfun = bind(&MyPair::multiply, _1); //#7 return x.multiply()
	cout << bound_memfun(ten_two) << endl; // 20

	auto bound_memdata = bind(&MyPair::a, ten_two); //#8 return ten_two.a
	cout << bound_memdata() << endl; //10

	auto bound_memdata2 = bind(&MyPair::b, _1); //#9 return x.b
	cout << bound_memdata2(ten_two) << endl; //2

	vector<int> v{ 15, 37, 94, 50, 73, 58, 28, 98 };
	int n = count_if(v.cbegin(), v.cend(), not1(bind2nd(less<int>(), 50)));
	cout << n << endl; //5

	auto fn = bind(less<int>(), _1, 50); //#10
	cout << count_if(v.cbegin(), v.cend(), fn) << endl; //3
	return 0;
}
解析:

a、#3通过bind绑定一般函数my_divide()传入函数的第一参数为10,第二参数为2,则通过结果fn_five()即可实现10// 2 = 5操作;

b、#4通过bind绑定一般函数my_divide()传入函数的第二参数为2,第一参数用符号_1表示第一参数未被绑定,则通过fn_half(10)将第一参数传入计算;

c、#5通过bind绑定一般函数my_divide(),而符号_2,_1表示绑定后要传入第二参数和第一参数,则通过fn_invert(10,2)分别将第二和第一参数传入计算;

d、#6通过bind绑定一般函数my_divider(),同时返回类型也指定是int,而通过符号_1,_2表示要传入第一参数和第二参数,则通过fn_rounding(10,2)传入计算;

e、#7通过bind绑定成员函数multiply(),而符号_1表示函数参数未传入,要要把声明对象数据传入,及bound_memfun(ten_two)计算;

f、#8通过bind绑定类成员a,且类数据ten_two已经传入,使用时直接用bound_memdata()进行计算;

f、#9通过bind绑定类成员b,且符号_1表示类数据未传入,需要使用bound_memdata2(ten_two)将数据传入计算;

g、#10通过bind绑定仿函数less<int>(),且将仿函数的第二参数传入50,第一参数采用符号_1表示要实际传入,则fn才能实现less的第二参数绑定。



函数适配器是一种特殊的函数对象,用于在函数调用中修改参数的顺序或值。`bind1st`和`bind2nd`是函数适配器的例子。 `bind1st`用于将一个二元函数(接受两个参数的函数)的第一个参数固定为一个特定的值。它接受一个二元函数和一个值作为参数,并返回一个新的函数对象,该对象将第一个参数绑定为给定值。这样,当调用新的函数对象时,它只需要一个参数,而不是两个。 例如,假设有一个二元函数`add`,它接受两个整数并返回它们的和。如果我们使用`bind1st`将第一个参数绑定为5,我们可以创建一个新的函数对象`add5`,它只需要一个参数,并将其与5相加。 ```cpp int add(int a, int b) { return a + b; } // 使用bind1st将第一个参数绑定为5 auto add5 = std::bind1st(add, 5); int result = add5(3); // 调用add5,相当于调用add(5, 3) // result 等于 8 ``` `bind2nd`与`bind1st`类似,但它将第二个参数固定为给定值。这样,新的函数对象在调用时只需要一个参数,并将其与给定值作为第二个参数传递给原始函数。 ```cpp int subtract(int a, int b) { return a - b; } // 使用bind2nd将第二个参数绑定为3 auto subtract3 = std::bind2nd(subtract, 3); int result = subtract3(7); // 调用subtract3,相当于调用subtract(7, 3) // result 等于 4 ``` 这些函数适配器可以方便地修改函数的参数顺序或固定某些参数的值,使其更适应特定的使用场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值