C++ 包装器—function
????? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ???????????????🎬慕斯主页:修仙—别有洞天
? ?????????????????????????????????????????????????????????今日夜电波:Duvet—B?a
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2:20━━━━━━?💟──────── 3:22
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ????🔄 ? ?? ? ? ? ?? ? ????
??????????????????????????????????????💗关注👍点赞🙌收藏您的每一次鼓励都是对我莫大的支持😍
目录
一、什么是function?
????????在C++中,std::function是一种模板类,它用于表示任意类型的函数或方法,可以作为函数参数或返回类型。std::function的提出可以用于替代函数指针,以此来降低使用回调函数的难度,它比普通函数指针更加的灵活和便利。
????????std::function的主要特点包括:
- 可以存储和执行任何类型的函数或方法,只要该函数或方法能够被复制(即它可以有一个副本)。
- 可以方便地对函数进行比较、拷贝、移动等操作。
- 可以通过std::bind函数或其他方式创建具有特定参数和返回类型的函数实例。
template< class R, class... Args >
class function<R(Args...)>;
对于以上各个部分的解析:
????????R表示函数的返回类型,Args表示函数的参数列表。std::function模板类生成的类可以用来存储任何符合这些类型的函数。
一个简单的例子:
#include <iostream>
#include <functional>
// 定义一个简单的函数
int add(int a, int b) {
return a + b;
}
int main() {
// 创建一个std::function实例,存储add函数
std::function<int(int, int)> func = add;
// 使用std::function执行add函数
int result = func(1, 2);
std::cout << "Result: " << result << std::endl;
return 0;
}
????????在这个例子中,我们首先定义了一个简单的函数add,然后使用std::function创建了一个函数实例func,并将其初始化为add函数。最后,我们使用func执行add函数,并输出结果。
需要注意的是,std::function并不是C++标准库的一部分,而是C++11引入的新特性之一。因此,在使用std::function之前,需要确保你的编译器已经支持C++11或更高版本。
????????对以上例子进行详细的分析:function的R的定义是根据add函数的返回类型定义为int,函数的参数列表为两个int也是因为add函数的两个传参为int。
二、function使用详解
包装基本的函数(普通、仿函数、lambda)
#include<iostream>
#include<functional>
#include<string>
#include <map>
using namespace std;
//普通函数
void swap_func(int& r1, int& r2)
{
int tmp = r1;
r1 = r2;
r2 = tmp;
}
//仿函数
struct Swap
{
void operator()(int& r1, int& r2)
{
int tmp = r1;
r1 = r2;
r2 = tmp;
}
};
int main()
{
int x = 0, y = 1;
cout << x << " " << y << endl;
//lambda
auto swaplambda = [](int& r1, int& r2) {
int tmp = r1;
r1 = r2;
r2 = tmp;
};
function<void(int&, int&)> f1 = swap_func;
f1(x, y);
cout << x << " " << y << endl << endl;
function<void(int&, int&)> f2 = Swap();
f2(x, y);
cout << x << " " << y << endl << endl;
function<void(int&, int&)> f3 = swaplambda;
f3(x, y);
cout << x << " " << y << endl << endl;
map<string, function<void(int&, int&)>> cmdOP = {
{"函数指针", swap_func},
{"仿函数", Swap()},
{"lambda", swaplambda},
};
cmdOP["函数指针"](x, y);
cout << x << " " << y << endl << endl;
cmdOP["仿函数"](x, y);
cout << x << " " << y << endl << endl;
cmdOP["lambda"](x, y);
cout << x << " " << y << endl << endl;
return 0;
}
包装静态成员函数
????????包装静态成员函数,我们需要指定类域,然后加上&用于成员函数取地址,当然因为是静态成员函数其实可以不加&,但是为了统一,我们最好加上。
class Plus
{
public:
static int plusi(int a, int b)
{
return a + b;
}
};
int main()
{
// 成员函数取地址,比较特殊,要加一个类域和&
function<int(int, int)> f1 = &Plus::plusi;
cout << f1(1, 2) << endl;
return 0;
}
包装普通成员函数
????????由于普通成员函数的包装还存在一个this,因此function中还需要传this,因此我们可以像以下的两种方式包装:一、传递指针,用指针去调用成员函数指针。二、传递对象,用对象去调用函数指针。(第二种可以理解成做了特殊处理)
class Plus
{
public:
static int plusi(int a, int b)
{
return a + b;
}
double plusd(double a, double b)
{
return a + b;
}
};
int main()
{
// 成员函数取地址,比较特殊,要加一个类域和&
function<int(int, int)> f1 = &Plus::plusi;
cout << f1(1, 2) << endl;
function<double(Plus*, double, double)> f2 = &Plus::plusd;
Plus ps;
cout << f2(&ps, 1.1, 2.2) << endl;
function<double(Plus, double, double)> f3 = &Plus::plusd;
cout << f3(Plus(), 1.11, 2.22) << endl;
return 0;
}
三、bind使用详解
// 原型如下:
template <class Fn, class... Args>
/* unspecified */ bind (Fn&& fn, Args&&... args);
// with return type (2)
template <class Ret, class Fn, class... Args>
/* unspecified */ bind (Fn&& fn, Args&&... args);
????????bind函数用于将一个可调用对象(如函数、lambda表达式等)与一组参数绑定,生成一个新的可调用对象。
????????第一个模板声明template <class Fn, class... Args> /* unspecified */ bind (Fn&& fn, Args&&... args);表示bind函数接受一个可调用对象fn和一组参数args,返回一个新的可调用对象。其中,Fn是可调用对象的类型,Args是参数的类型,...表示可变参数包。
????????第二个模板声明template <class Ret, class Fn, class... Args> /* unspecified */ bind (Fn&& fn, Args&&... args);表示bind函数接受一个可调用对象fn、一个返回类型Ret和一组参数args,返回一个新的可调用对象。其中,Ret是返回类型的类型,Fn是可调用对象的类型,Args是参数的类型,...表示可变参数包。
调整参数的顺序
????????如下我们可以用function进行bind改变函数传参的顺序,根据(placeholder::_第几个参数)来按照对应的位置调整顺序。如下:
int Sub(int a, int b)
{
return a - b;
}
int main()
{
function<int(int, int)> f1 = Sub;
cout << f1(10, 5) << endl;
// 调整参数顺序
function<int(int, int)> f2 = bind(Sub, placeholders::_2, placeholders::_1);
cout << f2(10, 5) << endl;
return 0;
}
调整参数个数,用bind写死参数
????????我们也可以用function进行bind通过写死一些参数来调整参数的个数,当然我们也是需要用(placeholder::_第几个参数)来按照对应的位置调整。如下:
int Sub(int a, int b)
{
return a - b;
}
int main()
{
function<int(int, int)> f1 = Sub;
cout << f1(10, 5) << endl;
// 调整参数顺序
function<int(int, int)> f2 = bind(Sub, placeholders::_2, placeholders::_1);
cout << f2(10, 5) << endl;
// 调整参数个数,有些参数可以bind时写死
function<int(int)> f3 = bind(Sub, 20, placeholders::_1);
cout << f3(5) << endl;
return 0;
}
用bind调整来包装成员函数
class Plus
{
public:
static int plusi(int a, int b)
{
return a + b;
}
double plusd(double a, double b)
{
return a + b;
}
};
int main()
{
function<double(Plus*, double, double)> f2 = &Plus::plusd;
Plus ps;
cout << f2(&ps, 1.1, 2.2) << endl;
function<double(Plus, double, double)> f3 = &Plus::plusd;
cout << f3(Plus(), 1.11, 2.22) << endl;
//用bind来写死Plus()从而简化代码
function<double(double, double)> f4 = bind(&Plus::plusd, Plus(), placeholders::_1, placeholders::_2);
cout << f4(1.11, 2.22) << endl;
return 0;
}
????????????????感谢你耐心的看到这里?( ′・?・` )比心,如有哪里有错误请踢一脚作者o(╥﹏╥)o!
????????????????????????????????????????????????????????????????给个三连再走嘛~
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!