C++ STL:function包装函数详解

C++ STL:function包装函数详解

文章目录

function包装1.包装普通函数2.包装成员函数3.包装函数对象(仿函数)4.包装lambda表达式5.对标准库函数再封装

为什么要用function包装?

function函数包装:

将一个复杂的函数包装成一个简单易看易懂的普通函数。

语法:

function < 函数返回类型(函数参数…)>

!!!!!在阅读本节前,我建议你应该首先了解这些知识:!!!!!! 什么是仿函数??? bind参数绑定怎么用???

function包装

1.包装普通函数

int add(int a, int b)

{

return a + b;

}

int main()

{

//包装普通函数

function F1(add);

cout << F1(5, 10) << endl;

return 0;

}

我们创建了一个普通的函数,这个函数接受两个int型数据,返回他们相加的值,我们使用function指定了一个int为返回值,两个int为参数的包装函数,这样我们创建的F1就已经包装好了add函数,可以使用直接列表初始化,也可以使用=赋值初始化,此后,就可以直接调用这个包装函数了。

2.包装成员函数

class Foo

{

public:

mutable int a, b;

Foo() = default;

Foo(const int& a, const int& b) :a(a), b(b){}

void Class()

{

cout << __FUNCTION__ << endl;

}

void operator()(int a, int b)

{

cout << __FUNCTION__ << ": " << a * b << endl;

}

};

int main()

{

//包装成员函数:首先要进行bind绑定

Foo a;

function F2_1 = bind(&Foo::operator(),Foo(), placeholders::_1, placeholders::_2);

function F2_2 = bind(&Foo::Class, Foo());

F2_1(5,122);

F2_2();

return 0;

}

我们具有一个类,类中有我们自己定义的成员函数,我们可以把成员函数包装成普通函数。 注意:

类成员函数的包装需要使用bind函数绑定为普通函数,然后进行包装。bind函数的用法: bind绑定函数详解

在function中,我们指定bind绑定后的函数为void返回类型,两个int的参数,这样我们的F2_1就是一个普通的接受两个int的参数,返回void的函数了。

3.包装函数对象(仿函数)

class Foo

{

public:

mutable int a, b;

void operator()(int a, int b)

{

cout << __FUNCTION__ << ": " << a * b << endl;

}

};

int main()

{

//包装函数对象(仿函数)

function F3 = bind(Foo(), placeholders::_1, placeholders::_2);

F3(50, 40);

return 0;

}

仿函数:就是一个实现了重载括号运算符的函数,包含了一些实现算法的基本功能: C++STL仿函数详解 假设你已经知道了仿函数,并且了解了bind 的函数工作原理,同样,我们使用function包装仿函数也需要一个bind先绑定为普通函数,然后再对绑定后的函数起个别名: 定义其为返回类型void,接受两个int类型的参数,这样我们的F3就是这个类型了,即接受两个int,返回void,我们可以很轻松的调用这个函数。

4.包装lambda表达式

int main()

{

//包装lambda表达式

function F4 = bind([](const int& a, const int& b) {cout <<__FUNCTION__<<" :: " << a << ": " << b << endl; }, placeholders::_1, placeholders::_2);

F4(669, 999);

return 0;

}

同样使用bind函数进行一次绑定,然后对F4函数进行包装,将此lambda表达式包装成一个接受int类型(const int& 类型也行),然后返回值为void 的普通函数,这样就能调用这个包装的函数了。

5.对标准库函数再封装

我们知道,在# include < function >文件中定义了很多的仿函数,我们能否直接借用他们,来当作我们自己的函数呢?

int main()

{

//function偷取标准库函数

function My_greater = bind(greater(), placeholders::_1, placeholders::_2);

cout << boolalpha << My_greater(50, 10) << endl;

function My_less = bind(less(), placeholders::_1, 20);

cout << boolalpha << My_less(10) << endl;

return 0;

}

bind的第一个参数实际上就是个仿函数,不过是标准库自带的仿函数,我们应该能很容易的看懂这个代码,他就是标准库自己封装的比较两个数字大于或者其他关系的仿函数,重载了括号运算符,我们完全可以自己写一个仿函数,不过如果你很懒,你可以直接使用function和bind函数绑定并且包装成你自己的函数,然后随意调用。

为什么要用function包装?

我们可以思考一下为什么要使用function包装

这是使用auto自动推断出的bind绑定成员函数后的函数类型:

auto F2_1 = bind(&Foo::operator(),Foo(), placeholders::_1, placeholders::_2);

F2_1的类型:std::_Binder const &,std::_Ph< 2 > const &>

对,你没看错,就是这样的,也就是说,如果你要自己手写它的数据类型,让你对着抄你都抄不对,所以我们必须使用auto来自动推断bind函数的类型。

但是我们使用auto未免不直观,我们可以使用function自动包装成简单的类型,只需要指定原函数的返回类型和参数类型即可:

function F2_1 = bind(&Foo::operator(),Foo(), placeholders::_1, placeholders::_2);

包装后的F2_1的函数类型:std::function

是不是一眼就看出来了,这是一个接受两个int,返回类型为void的函数,这样我们简化了auto自动推断的类型,同时又不缺失函数的功能,简直太美妙了。

相关推荐

道地药材 煅龙齿 1000g/袋
365bet手机

道地药材 煅龙齿 1000g/袋

📅 09-09 👁️ 1045
960麒麟是多少nm?
365bet亚洲版官网

960麒麟是多少nm?

📅 07-17 👁️ 3780
中国十大下雪城市有哪些 国内冬天必下雪的城市盘点
365体育怎么打不开网址

中国十大下雪城市有哪些 国内冬天必下雪的城市盘点

📅 07-02 👁️ 9992