c++的可调用对象 有c++
void afuncToCall() { cout << "call me"<<"\n"; } //1.call function afuncToCall();
void func(int i){ cout << "a function called by function pointer i= "<<i<<"\n"; } //声明一个函数指针 void(*f)(int i); //对函数指针赋值 f=func; //调用指针函数 f(5);
或者使用typedef缩写函数指针函数
//function pointer typedef void(*AbleCallFuncP)(int i) ; //2.function pointer AbleCallFuncP callFuncPointer= func; callFuncPointer(5);
auto flambda = [](int i){ cout << "lambda i is " << i << "\n"; }; flambda(7);
#include <functional> void func(int i){ cout << "a function called by bind object i= "<<i<<"\n"; } auto fbind = bind(func,std::placeholders::_1); fbind(9);
struct callableStruct { int operator()(int val){ return (val<0)?-val:val; } }; // callableStruct callableSut; int i = callableSut(-2);
如今,咱们拥有了5种函数调用方式,那么,在一个项目里,咱们极可能但愿使用一个统一的函数表来管理这些函数调用对象,以上面的函数为例,咱们其实拥有了5个参数为int类型的调用对象,使用map能够方便地实现函数表;指针
只是,问题在于,这5种可调用对象的类型是不一样的,咱们没法将他们使用同一种类型放入map的second字段中,因而万能的C++标准大神们发明了function类模板来解决这个问题。code
罗列5种可调对象以下:对象
//function void afuncToCall(int i) { cout << "call me a plain functon i is "<<i <<"\n"; } //function pointer typedef void(*AbleCallFuncP)(int i) ; //called by function pointer void func1(int i){ cout << "a function called by function pointer i= "<<i<<"\n"; } //called by bind void func2(int i){ cout << "a function called by bind i= "<<i<<"\n"; } //callable class struct callableStruct { void operator()(int i){ cout << "a function called by callableStruct i= "<<i<<"\n"; } };
//1.call function //afuncToCall(); // //2.function pointer AbleCallFuncP callFuncPointer= func1; //3.lambda auto flambda = [](int i){ cout << "lambda i is " << i << "\n"; }; //4 bind auto fbind = bind(func2,std::placeholders::_1); //5.operator () callableStruct callableSut;
让咱们用function统一它们的类型string
#include <functional> #include <map> #include <string> // using std::map; void TestCallableObj() { typedef function<void(int)> FuncVI; typedef map<string,FuncVI> FuncAbleObjMap; FuncAbleObjMap callableObjMap; callableObjMap.insert(FuncAbleObjMap::value_type(string("plain function call"),afuncToCall)); callableObjMap.insert(FuncAbleObjMap::value_type(string("function pointer call"),callFuncPointer)); callableObjMap.insert(FuncAbleObjMap::value_type(string("lambda call"),flambda)); callableObjMap.insert(FuncAbleObjMap::value_type(string("bind call"),fbind)); callableObjMap.insert(FuncAbleObjMap::value_type(string("operator() call"),callableStruct())); callableObjMap["plain function call"](1); callableObjMap["function pointer call"](2); callableObjMap["lambda call"](3); callableObjMap["bind call"](4); callableObjMap["operator() call"](5); }
输出结果io
call me a plain functon i is 1 a function called by function pointer i= 2 lambda i is 3 a function called by bind i= 4 a function called by callableStruct i= 5
因而可知,经过function模板,咱们将类型本不一样的5个可调用对象打包成统一的类型,由于它们的返回值和参数类型是彻底同样的。经过函数表的使用,咱们能够写出封装更好的调用函数。function
若是以为这样的调用太繁琐,可使用宏来缩写下
好比:模板
#define CALL1(x) callableObjMap[#x](1); CALL1(plain function call); CALL1(bind call);
备注,本文没有涉及到函数成员函数 和静态成员函数的调用,权当归类到函数一类了。可是其调用细节和函数仍是有差别的。class