<三>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;

}
posted @ 2022-12-07 14:47  Hello_Bugs  阅读(144)  评论(0编辑  收藏  举报