函数对象形式上是怎样的图像(function函数对象类型的应用示例)
std::function是一组函数对象包装类的模板 ,实现了一个泛型的回调机制 。function与函数指针比较相似 ,优点在于它允许用户在目标的实现上拥有更大的弹性,即目标既可以是普通函数 ,也可以是函数对象和类的成员函数 ,而且可以给函数添加状态 。
声明一个function时 ,需要给出所包装的函数对象的返回值类型和各个参数的类型 。比如 ,声明一个function ,它返回一个bool类型并接受一个int类型和一个float类型的参数 ,可以像下面这样:
function<bool (int, float)> f; 下面简要介绍一下function的比较重要的几个接口 。function(); 缺省构造函数 ,创建一个空的函数对象 。如果一个空的function被调用 ,将会抛出一个类型为bad_function_call的异常 。
template function(F g); 这个泛型的构造函数接受一个兼容的函数对象 ,即这样一个函数或函数对象,它的返回类型与被构造的function的返回类型或者一样 ,或者可以隐式转换 ,并且它的参数也要与被构造的function的参数类型或者一样,或者可以隐式转换 。
注意 ,也可以使用另外一个function实例来进行构造 。这样做 ,并且function g为空,则被构造的function也为空 。使用空的函数指针和空的成员函数指针也会产生空的function。如果这样做 ,并且function g为空 ,则被构造的function也为空 。使用空的函数指针和空的成员函数指针也会产生空的function 。
template function(reference_wrapper g); 这个构造函数与前一个类似 ,但它接受的函数对象包装在一个reference_wrapper中 ,用以避免通过值来传递而产生函数或函数对象的一份拷贝。这同样要求函数对象兼容于function的签名 。
function& operator=(const function& g); 赋值操作符保存g中的函数或函数对象的一份拷贝;如果g为空 ,被赋值的函数也将为空 。
template function& operator=(F g);
这个泛型赋值操作符接受一个兼容的函数指针或函数对象。
注意 ,也可以用另一个 function 实例(带有不同但兼容的签名)来赋值 。这同样意味着 ,如果g是另一个function实例且为空 ,则赋值后的函数也为空 。赋值一个空的函数指针或空的成员函数指针也会使function为空 。bool empty() const; 这个成员函数返回一个布尔值 ,表示该function是否含有一个函数或函数对象 。如果有一个目标函数或函数对象可被调用,它返回 false 。因为一个function可以在一个布尔上下文中测试 ,或者与0进行比较 ,因此这个成员函数可能会在未来版本的库中被取消,你应该避免使用它 。
void clear(); 这个成员函数清除 function, 即它不再关联到一个函数或函数对象 。如果function已经是空的 ,这个调用没有影响 。在调用后 ,function肯定为空 。令一个function为空的首选方法是赋0给它;clear 可能在未来版本的库中被取消。
result_type operator()(Arg1 a1, Arg2 a2, ..., ArgN aN) const; 调用操作符是调用function的方法 。你不能调用一个空的 function ,那样会抛出一个bad_function_call的异常 。调用操作符的执行会调用function中的函数或函数对象 ,并返回它的结果。
代码1
void hello1(){ cout<<"hello1()"<<endl; } void hello2(string str){ cout<<"hello2(string str)"<<endl; } int sum(int a ,int b){ return a+b; } int main(){ function<void()> func1=hello1;或 function<void()> func11(hello1); func1(); //=》 func1.operator() =>hello1() function<void(string)> func2=hello2; func2("hello");// =>func2.operator()("hello")=>hello2("hello") function<int(int,int)> func3=sum; int ret = func3(20,30);// int ret = func3.operator()(20,30) =>sum(20,30) //通过函数类型实例化function ,通过function调用operator()函数的时候,需要根据函数类型传入相应的参数 }代码2
class Test{ public: void say(string str){cout<str<<endl;} } int main(){ //注意第一参数是一个隐藏的参数,Test 指针 function<void (Test * ptest , string str)> func=&Test::say; func(&Test(),"hello Call Say()"); }代码3,使用示例
#include <iostream> #include <string> #include <map> #include <functional> using namespace std; void showNew() { string str = "<新建>"; cout << str << endl; } void showFile() { string str = "<文件>"; cout << str << endl; } void showAdd() { string str = "<添加>"; cout << str << endl; } void showClose() { string str = "<关闭>"; cout << str << endl; } void showExit() { string str = "<退出>"; cout << "<退出>" << endl; } int main() { map<int, function<void()>> mp; function<void()> f1 = showNew; function<void()> f2 = showFile; function<void()> f3 = showAdd; function<void()> f4 = showClose; mp.insert(pair<int, function<void()>>(1, f1)); mp.insert(pair<int, function<void()>>(2, f2)); mp.insert(pair<int, function<void()>>(3, f3)); mp.insert(pair<int, function<void()>>(4, f4)); for (int i = 1; i <= 4; i++) { mp.find(i)->second(); } system("pause"); return 0; }创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!