您的位置:首页 > 编程语言 > C语言/C++

bind--C++11

2016-01-11 20:24 387 查看
bind是一组用于函数绑定的模板。在对某个函数进行绑定时,可以指定部分参数或全部参数,也可以不指定任何参数,还可以调整各个参数间的顺序。对于未指定的参数,可以使用占位符_1、_2、_3来表示。-1表示绑定后的函数的第1个参数,_2表示绑定后的函数的第2个参数,其他依次类推。

bind可以绑定到普通函数、类的成员函数和类的成员变量。下面依次来讲解。

一:绑定到普通函数

首先我们定义一个函数my_divide,用来求得两个数的商。

#include<iostream>
#include<functional>

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

int main()
{
	using namespace std::placeholders;                        // adds visibility of _1, _2, _3,...  
	
	// binding functions:  
	auto fn_five = std::bind(my_divide, 10, 2);               // returns 10/2  
	std::cout << fn_five() << '\n';                           // 5  

	auto fn_half = std::bind(my_divide, _1, 2);               // returns x/2  
	std::cout << fn_half(10) << '\n';                         // 5  

	auto fn_invert = std::bind(my_divide, _2, _1);            // returns y/x  
	std::cout << fn_invert(10, 2) << '\n';                    // 0.2  

	auto fn_rounding = std::bind<int>(my_divide, _1, _2);     // returns int(x/y)  
	std::cout << fn_rounding(10, 3) << '\n';

	return 0;
}


二:绑定成员函数

#include<iostream>
#include<functional>

struct MyPair 
{
	double a, b;
	double multiply() { return a*b; }
};

int main()
{
	using namespace std::placeholders;                          // adds visibility of _1, _2, _3,...  
	
	MyPair ten_two = { 10,2 };

	auto bound_member_fn = std::bind(&MyPair::multiply, _1);    // returns x.multiply()  
	std::cout << bound_member_fn(ten_two) << '\n';              // 20  

	auto bound_member_data = std::bind(&MyPair::a, ten_two);    // returns ten_two.a  
	std::cout << bound_member_data() << '\n';                   // 10  

	return 0;
}


#include<iostream>  
#include<string>  
#include<functional>//std::bind  
using namespace std;

class Base
{
public:
	Base(int x = 0) :data(x) {}
	void show(string name) { cout << name << endl; }
	static int getNum() { return 10; }
	int operator()(int i, int j, int k) { return i + j + k; }
private:
	int data;
};

int main()
{
	using namespace std::placeholders;

	Base one(5);

	//1.绑定类成员函数  
	auto show1 = bind(&Base::show, one, _1);
	show1("123456");                                       //123456 
	 
	auto show2 = bind(&Base::show, one, "123456");
	show2();                                               //123456  

	//2.绑定静态成员函数  
	auto getnum = bind(&Base::getNum);
	cout << getnum() << endl;                              //10  

	//3.绑定operator函数  
	auto oper = bind(&Base::operator(), one, _1, _2, 0);
	cout << oper(1, 2) << endl;                            //3
	
	auto oper1 = bind(Base(), _1, _2, 0);
	cout << oper1(1, 2) << endl;                           //3

	return 0;
}


#include<iostream>  
#include<functional>//std::bind  
using namespace std;

struct TAdd
{
	int Add(int x, int y)
	{
		return x + y;
	}
};

int main()
{
	using namespace std::placeholders;

	TAdd tAdd;
	TAdd *p = new TAdd();

	cout << bind(&TAdd::Add, tAdd, 2, 3)() << endl;   //5
	cout << bind(&TAdd::Add, p, 2, 3)() << endl;      //5
	
	return 0;
}


三:绑定成员变量

#include<iostream>  
#include<functional>//std::bind  
#include<map>
#include<string>
#include<algorithm>
using namespace std;

void Output(const string &name)
{
	cout << name << endl;
}

int main()
{
	using namespace std::placeholders;

	map<int, string> m1;
	m1.insert(pair<int, string>(1, "liuyi"));
	m1.insert(pair<int, string>(2, "lisi"));

	for_each(m1.begin(), m1.end(), bind(Output, bind(&map<int,string>::value_type::second, _1)));

	return 0;
}


四:其他用法

1.嵌套绑定

假如要实现对一组向量进行排序:

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

class CPerson
{
	int age;
public:
	CPerson(int _age=0):age(_age){}
	int GetAge() { return age; }
};

int main()
{
	using namespace std::placeholders;

	vector<CPerson> vper;

	vper.push_back(CPerson(2));
	vper.push_back(CPerson(4));
	vper.push_back(CPerson(1));
	vper.push_back(CPerson(3));

	sort(vper.begin(), vper.end(), bind(less<int>(), bind(&CPerson::GetAge, _1), bind(&CPerson::GetAge, _2)));
	for_each(vper.begin(), vper.end(), [](CPerson x) {cout << x.GetAge() << endl; });

	return 0;
}


假设有一个整数的向量,现在要获取其中大于20且小于30的个数:

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

int main()
{
	using namespace std::placeholders;

	vector<int> v;

	v.push_back(10);
	v.push_back(15);
	v.push_back(21);
	v.push_back(26);
	v.push_back(31);
	
	auto x = count_if(
		v.begin(), 
		v.end(), 
		bind(logical_and<bool>(), bind(greater<int>(), _1, 20), bind(less<int>(), _2, 30))//same as " [](int a) {return (a > 20) && (a < 30); } "
	);
	
	cout << x << endl;      //3

	return 0;
}


2.特别注意点

bind中传值默认是值传递,当然可以改为引用传递

#include<iostream>  
#include<functional>//std::bind  

using namespace std;

void func(int &x)
{
	x++;
}

int main()
{
	using namespace std::placeholders;

	//默认值传递
	int n = 0;
	bind(func, n)();
	cout << n << endl;    //0

	//引用传递
	bind(func, ref(n))();
	cout << n << endl;    //1

	return 0;
}


参考自: http://www.cnblogs.com/hujian/archive/2012/12/08/2809298.htmlhttp://www.cplusplus.com/reference/functional/bind/?kw=bind
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: