C++中有几种可调用对象:函数,指针,lambda表达式,bind创建的对象以及重载了调用运算符的类。
通过function类型可以将多个不同类型的对象,整合到一个类型中。
基础的thread调用的时候,传入的是一个函数指针。
同理可得,还可以传入一个用户定义的函数对象,传入一个类的内部函数,传入一个命名完成的lambda表达式或者传入一个未命名的lambda表达式。
使用多种类型的可调用对象构建一个计算器
int add(int a,int b)
{
return a+b;
}
auto mod = [](int a, int b){return a % b;};
struct divide
{
int operator()(int a,int b){
return a/b; }
}
可以通过map实现一个函数表,通过string类型的运算符找到指定的处理方式。
运算符到函数指针的映射可以设置为:
map binops;
但是mod的lambda对象和函数对象类不能添加到binops这个map中;
可以通过C++11 标准库类型function来解决上述问题,将所有相同调用方式的可调用对象集合到一处。
function定义在functional的头文件中
#include
function f; //f是一个用来存储可调用对象的空function,这些可调用对象的调用形式应该与T相同
function f(nullptr); //显示构造一个空的function
function f(obj); //f中存储可调用对象obj的副本
f //若f作为条件:当f中包含一个可调用对象则为真,否则为假
f(args) //调用f中的对象,参数是args
可以通过function将之前的几个不同类型的可调用类型集合到一起
function f1 = add;//函数指针
function f2 = divide();//函数对象类的对象
function f3 = [](int a,int b){return a*b;};//lambda表达式
因此,可以重新定义map
map> binpos;
map> binpos=
{
{"+",add}, {"-",std::minus()}, //标准库函数对象
{"/",divide()}, //用户定义的函数对象 {"%",mod}, //命名的lambda表达式
{"*",[](int a,int b){return a*b;}}, //未命名的lambda表达式
};
通过map下标即可调用各种可调用对象,完成各种运算
binops["+"](1,2); //相当于调用add(1,2)
若有函数重载的情况,则不能简单的进行传入,否则function调用的时候不能确定调用哪一个。
int add(int a, int b);
class DataMe;
DataMe& add(DataMe& a,DataMe& b);
可以将其中一个用函数指针或者lambda表达式来代替。
auto ptr_add=add;
int (*fp)(int ,int ) = add;
auto add = [](int a,int b){return a+b;};