此篇博客主要包含三个C++11的新特性。可用于绑定接收到其他进程消息后的消息处理函数。
使用时需要包含头文件functional。在实际工作中可实现函数回调,std::function的实例可以对任何可以调用的目标实体进行存储、复制、和调用操作,这些目标实体包括普通函数、Lambda表达式(也是C++11的特性)、函数指针、以及其它函数对象等。
//代码出自链接:http://www.jellythink.com/archives/771
#include
#include
using namespace std;
std::function< int(int)> Functional;
// 普通函数
int TestFunc(int a)
{
return a;
}
// Lambda表达式
auto lambda = [](int a)->int{ return a; };
// 仿函数(functor)
class Functor
{
public:
int operator()(int a)
{
return a;
}
};
// 1.类成员函数
// 2.类静态函数
class TestClass
{
public:
int ClassMember(int a) { return a; }
static int StaticMember(int a) { return a; }
};
int main()
{
// 普通函数
Functional = TestFunc;
int result = Functional(10);
cout << "普通函数:"<< result << endl;
// Lambda表达式
Functional = lambda;
result = Functional(20);
cout << "Lambda表达式:"<< result << endl;
// 仿函数
Functor testFunctor;
Functional = testFunctor;
result = Functional(30);
cout << "仿函数:"<< result << endl;
// 类成员函数
TestClass testObj;
Functional = std::bind(&TestClass::ClassMember, testObj, std::placeholders::_1);
result = Functional(40);
cout << "类成员函数:"<< result << endl;
// 类静态函数
Functional = TestClass::StaticMember;
result = Functional(50);
cout << "类静态函数:"<< result << endl;
return 0;
}
可以看到function能够存储上述类型函数,并且完成调用。
定义:
simple(1)
template
/* unspecified */ bind (Fn&& fn, Args&&... args);
with return type (2)
template
/* unspecified */ bind (Fn&& fn, Args&&... args);
绑定器,返回基于fn的函数对象,但其参数绑定到args。
每个参数可以绑定到值或占位符:
// bind example
#include // std::cout
#include // std::bind
// a function: (also works with function object: std::divides my_divide;)
double my_divide (double x, double y) {return x/y;}
struct MyPair {
double a,b;
double multiply() {return a*b;}
};
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 (my_divide,_1,_2); // returns int(x/y)
std::cout << fn_rounding(10,3) << '\n'; // 3
MyPair ten_two {10,2};
// binding members:
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;
}
可以看到,bind绑定的参数,可以部分绑定某个值,部分绑定占位符,占位符的顺序也可以自己指定(相当于可以改变调用时的传参顺序),还是很灵活的。这里面不可避免用到了placeholders,下面来讲。
定义很简单:
namespace placeholders {
extern /* unspecified */ _1;
extern /* unspecified */ _2;
extern /* unspecified */ _3;
// ...
}
他的应用就是bind绑定参数时的占位符,当调用bind返回的函数对象时,带有占位符_1的参数被调用中的第一个参数替换,_2被调用中的第二个参数替换,依此类推。
可以实现消息处理的分配器,用unordered_map做存储,key为消息名,value为对应的处理函数,再用bind绑定处理函数,eg:
std::unordered_map> dealfuncs;
dealfuncs[cmdname] = std::bind(&someClass::func, this, _1,_2,...);
实现绑定的函数,在消息到来时,根据消息名查找到对应的消息处理函数并调用。