慕斯主页:修仙—别有洞天
♈️今日夜电波:Duvet—Bôa
2:20━━━━━━️──────── 3:22
◀️ ⏸ ▶️ ☰
关注点赞收藏您的每一次鼓励都是对我莫大的支持
目录
一、什么是function?
二、function使用详解
包装基本的函数(普通、仿函数、lambda)
包装静态成员函数
包装普通成员函数
三、bind使用详解
调整参数的顺序
调整参数个数,用bind写死参数
用bind调整来包装成员函数
在C++中,std::function是一种模板类,它用于表示任意类型的函数或方法,可以作为函数参数或返回类型。std::function的提出可以用于替代函数指针,以此来降低使用回调函数的难度,它比普通函数指针更加的灵活和便利。
std::function的主要特点包括:
- 可以存储和执行任何类型的函数或方法,只要该函数或方法能够被复制(即它可以有一个副本)。
- 可以方便地对函数进行比较、拷贝、移动等操作。
- 可以通过std::bind函数或其他方式创建具有特定参数和返回类型的函数实例。
template< class R, class... Args >
class function;
对于以上各个部分的解析:
R表示函数的返回类型,Args表示函数的参数列表。std::function模板类生成的类可以用来存储任何符合这些类型的函数。
一个简单的例子:
#include
#include
// 定义一个简单的函数
int add(int a, int b) {
return a + b;
}
int main() {
// 创建一个std::function实例,存储add函数
std::function 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。
#include
#include
#include
#include
包装静态成员函数,我们需要指定类域,然后加上&用于成员函数取地址,当然因为是静态成员函数其实可以不加&,但是为了统一,我们最好加上。
class Plus
{
public:
static int plusi(int a, int b)
{
return a + b;
}
};
int main()
{
// 成员函数取地址,比较特殊,要加一个类域和&
function 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 f1 = &Plus::plusi;
cout << f1(1, 2) << endl;
function f2 = &Plus::plusd;
Plus ps;
cout << f2(&ps, 1.1, 2.2) << endl;
function f3 = &Plus::plusd;
cout << f3(Plus(), 1.11, 2.22) << endl;
return 0;
}
// 原型如下:
template
/* unspecified */ bind (Fn&& fn, Args&&... args);
// with return type (2)
template
/* unspecified */ bind (Fn&& fn, Args&&... args);
bind函数用于将一个可调用对象(如函数、lambda表达式等)与一组参数绑定,生成一个新的可调用对象。
第一个模板声明template
/* unspecified */ bind (Fn&& fn, Args&&... args);表示bind函数接受一个可调用对象fn和一组参数args,返回一个新的可调用对象。其中,Fn是可调用对象的类型,Args是参数的类型,...表示可变参数包。 第二个模板声明template
/* 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 f1 = Sub;
cout << f1(10, 5) << endl;
// 调整参数顺序
function f2 = bind(Sub, placeholders::_2, placeholders::_1);
cout << f2(10, 5) << endl;
return 0;
}
我们也可以用function进行bind通过写死一些参数来调整参数的个数,当然我们也是需要用(placeholder::_第几个参数)来按照对应的位置调整。如下:
int Sub(int a, int b)
{
return a - b;
}
int main()
{
function f1 = Sub;
cout << f1(10, 5) << endl;
// 调整参数顺序
function f2 = bind(Sub, placeholders::_2, placeholders::_1);
cout << f2(10, 5) << endl;
// 调整参数个数,有些参数可以bind时写死
function f3 = bind(Sub, 20, placeholders::_1);
cout << f3(5) << endl;
return 0;
}
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 f2 = &Plus::plusd;
Plus ps;
cout << f2(&ps, 1.1, 2.2) << endl;
function f3 = &Plus::plusd;
cout << f3(Plus(), 1.11, 2.22) << endl;
//用bind来写死Plus()从而简化代码
function f4 = bind(&Plus::plusd, Plus(), placeholders::_1, placeholders::_2);
cout << f4(1.11, 2.22) << endl;
return 0;
}
感谢你耐心的看到这里ღ( ´・ᴗ・` )比心,如有哪里有错误请踢一脚作者o(╥﹏╥)o!
给个三连再走嘛~