0
点赞
收藏
分享

微信扫一扫

bind--C++11

花明 2022-12-07 阅读 60


        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.cplusplus.com/reference/functional/bind/?kw=bind​​




举报

相关推荐

0 条评论