1.std:bind
std:bind 是一个函数模板,可以用来绑定一切函数
1.1 绑定普通成员函数,普通静态成员函数,普通模板函数
例子:
#include <functional>
#include <iostream>
#include <cstdio>
void fun(int a, int b)
{
std::cout <<a+b<<std::endl;
}
int main()
{
auto funBind = std::bind(fun, 4, 6);
funBind();
return 0;
}
结果为
10
上面的例子中函数fun被绑定到了funBind中,fun中的参数被绑定到了一个固定的值,当然你也可以不指定它的值,在绑定值时给它一个缺省值,即绑定到占位符(std::placeholders )上,如下:
#include <functional>
#include <iostream>
#include <cstdio>
void fun(int a, int b)
{
std::cout << a + b << std::endl;
}
static void staticfun(int a, int b)
{
std::cout << a + b << std::endl;
}
template<typename A, typename B>
inline void addFun(A a, B b)
{
std::cout << a + b << std::endl;
}
int main()
{
auto funBind = std::bind(fun, std::placeholders::_1, 6);
funBind(4);
auto funBind1 = std::bind(staticfun, std::placeholders::_1, std::placeholders::_2);
funBind1(5, 6);
auto funBind2 = std::bind(addFun<int,int>, std::placeholders::_1, std::placeholders::_2);
funBind2(6, 6);
return 0;
}
结果:
10
11
12
需要注意的是:绑定到模板函数的时候,第一个参数需要指定参数的类型
1.2 绑定类成员函数,类静态成员函数,类模板函数
需要注意的是:在绑定类成员函数时,bind的第一个参数为对象的成员函数指针,第二个参数为一个具体的对象实例指针,如下
#include <functional>
#include <iostream>
#include <cstdio>
class S {
public:
void fun(int a, int b)
{
std::cout << a + b << std::endl;
}
static void staticfun(int a, int b)
{
std::cout << a + b << std::endl;
}
template<typename A, typename B>
inline void addFun(A a, B b)
{
std::cout << a + b << std::endl;
}
};
int main()
{
S s;
auto funBind = std::bind(&S::fun,&s,std::placeholders::_1, 6);
funBind(4);
auto funBind1 = std::bind(&S::staticfun, std::placeholders::_1, std::placeholders::_2);
funBind1(5,6);
auto funBind2 = std::bind(&S::addFun<int,int>, &s,std::placeholders::_1, std::placeholders::_2);
funBind2(6, 6);
return 0;
}
结果:
10
11
12
需要注意的是成员函数的访问权限为public ,在绑定静态成员函数时,第二个参数不需要指定具体对象实例的地址
1.3 绑定引用参数
先看例子:
#include <functional>
#include <iostream>
#include <cstdio>
int add(int& a, const int& b)
{
return a+b;
}
int main()
{
int a = 2, b = 4;
auto funcBind = std::bind(add, std::ref(a), std::cref(b));
std::cout << funcBind() << std::endl;
return 0;
}
```c
结果为:
```c
6
在上面的例子a为普通引用,在绑定传递值时调用ref即可,而b为常量引用,在绑定传递值时调用cref即可
1.4 绑定lambda表达式
#include <functional>
#include <iostream>
#include <cstdio>
auto lambda = [](int a, int b)
{
return a + b;
};
int main()
{
int a = 2, b = 4;
auto funcBind = std::bind(lambda, a, b);
std::cout << funcBind() << std::endl;
return 0;
}
结果:
6
2.std::function
2.1 封装普通函数/静态函数/lambda表达式
std::function 是一个函数模板类,是一个类,定义在头文件可以用其定义不同的对象,对象的类型可以是普通函数,静态函数以及Lambda表达式 ,在不用std::function 之前,定义一个函数指针通常用以下方法定义,如:
typedef void (*funPtr)(int,int);
使用std::function 之后,这样定义
std::function<void(int ,int)> funPtr;
通常这样子使用,先定义一个函数,再将这个函数指针赋值给一个std::function 对象,如下
#include <functional>
#include <iostream>
#include <cstdio>
void fun(int a, int b)
{
std::cout << a + b << std::endl;
}
static void fun1(int a, int b)
{
std::cout << a + b << std::endl;
}
auto lambda = [](int a, int b)
{
std::cout << a + b << std::endl;
};
int main()
{
std::function<void(int, int)> funPtr = fun;
funPtr(1, 2);
std::function<void(int, int)> funPtr1 = fun1;
funPtr1(2, 2);
std::function<void(int, int)> funPtr2 = lambda;
funPtr2(3, 2);
return 0;
}
结果:
3
4
5
2.2 绑定成员函数/静态成员函数/函数模板/成员变量
在封装成员函数/静态成员函数时,std::function 和std::bind 搭配使用
#include <functional>
#include <iostream>
#include <cstdio>
class S {
public:
int num;
void fun(int a, int b)
{
std::cout << a + b << std::endl;
}
static void staticfun(int a, int b)
{
std::cout << a + b << std::endl;
}
template<typename A, typename B>
inline void addFun(A a, B b)
{
std::cout << a + b << std::endl;
}
};
int main()
{
S s;
std::function<void(int, int)> funBind1 = std::bind(&S::staticfun, std::placeholders::_1, std::placeholders::_2);
funBind1(5, 6);
std::function<void(int, int)> funBind2 = std::bind(&S::addFun<int, int>, &s, std::placeholders::_1, std::placeholders::_2);
funBind2(6, 6);
std::function<int& ()> MyValue = std::bind(&S::num, &s);
MyValue() = 1000;
std::cout << "num = "<<s.num<< std::endl;
return 0;
}
结果:
11
12
num = 1000
需要注意的是不可以使用 std::function指向类的非静态成员,可以用函数指针的形式表示或者在类中直接绑定,如下:
#include <iostream>
#include <vector>
#include <functional>
class Father
{
public:
void Called() {
for (int i = 0; i < Vec.size(); i++)
Vec[i]();
}
protected:
std::vector<std::function<void()>> Vec;
};
class Son : public Father
{
public:
Son()
{
std::function<void()> fun1 = std::bind(&Son::A, this);
std::function<void()> fun2 = std::bind(&Son::B, this);
Vec.push_back(fun1);
Vec.push_back(fun2);
}
private:
void A() { std::cout << "A\n"; }
void B() { std::cout << "B\n"; }
};
int main()
{
Son d;
d.Called();
return 0;
}
结果:
A
B
|