C++ 包装器—function

                                                         慕斯主页修仙—别有洞天

                                                         ♈️今日夜电波:Duvet—Bôa

                                                                2:20━━━━━━️──────── 3:22
                                                                       ◀️   ⏸   ▶️    ☰  

                                      关注点赞收藏您的每一次鼓励都是对我莫大的支持


目录

一、什么是function?

二、function使用详解

包装基本的函数(普通、仿函数、lambda)

包装静态成员函数

包装普通成员函数

三、bind使用详解

调整参数的顺序

调整参数个数,用bind写死参数

用bind调整来包装成员函数


一、什么是function?

        在C++中,std::function是一种模板类,它用于表示任意类型的函数或方法,可以作为函数参数或返回类型。std::function的提出可以用于替代函数指针,以此来降低使用回调函数的难度,它比普通函数指针更加的灵活和便利。

        std::function的主要特点包括:

  • 可以存储和执行任何类型的函数或方法,只要该函数或方法能够被复制(即它可以有一个副本)。
  • 可以方便地对函数进行比较、拷贝、移动等操作。
  • 可以通过std::bind函数或其他方式创建具有特定参数和返回类型的函数实例。
template< class R, class... Args >
  class function;

C++ 包装器—function_第1张图片

对于以上各个部分的解析:

        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。

二、function使用详解

包装基本的函数(普通、仿函数、lambda)

#include
#include
#include
#include 
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 f1 = swap_func;
	f1(x, y);
	cout << x << " " << y << endl << endl;

	function f2 = Swap();
	f2(x, y);
	cout << x << " " << y << endl << endl;

	function f3 = swaplambda;
	f3(x, y);
	cout << x << " " << y << endl << endl;

	map> 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;
}

C++ 包装器—function_第2张图片

包装静态成员函数

        包装静态成员函数,我们需要指定类域,然后加上&用于成员函数取地址,当然因为是静态成员函数其实可以不加&,但是为了统一,我们最好加上。

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

C++ 包装器—function_第3张图片

包装普通成员函数

        由于普通成员函数的包装还存在一个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;
}

C++ 包装器—function_第4张图片

三、bind使用详解

// 原型如下:
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;
}

调整参数个数,用bind写死参数

        我们也可以用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;
}

用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 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!

C++ 包装器—function_第5张图片

                                                                给个三连再走嘛~

你可能感兴趣的:(C++修仙,筑基中,c++,开发语言,算法)