C++:std::function模板类

一:function定义

  • 类模板 std::function是一种通用的多态函数包装器,它的实例可以对任何可以调用的目标实体进行存储,复制和调用操作。
  • 简单的来说:C++中有几种可调用对象:函数,指针,lambda表达式,bind创建的对象,以及重载了调用运算符的类,function是一种类型,这种类型可以将上述不同类型对象,整合到一个类型中。
  • 它是对C++中现有的可调用实体的一种类型安全的包裹(相对来说,函数指针的调用不是类型安全的)

二:function实例

1:定义一个模板 :  typedef function<int(int)> Funtional

2:  此模板可以包装接收:普通函数,lambda函数,仿函数,静态成员函数,成员函数

#include<iostream>
#include<string>
#include<functional>
using namespace std;

// 声明一个模板
typedef function<int(int)> Functional;

// 普通函数
int testFunc(int a) {
	return a+1;
}

// lambda expression
auto lambda = [](int a)->int
{
	return a + 2;
};

// functor仿函数
class Functor
{
public:
	int operator()(int a) {
		return a + 3;
	}
};

// 类的成员函数和类的静态成员函数
class CTest {
public:
	int Func(int a) {
		return a + 4;
	}

	static int SFunc(int a) {
		return a + 5;
	}
};

int main() {
	// 封装普通函数
	Functional obj = testFunc;
	cout << "普通函数:" << obj(0) << endl;

	// 封装lambda表达式
	obj = lambda;
	cout << "lambda函数:" << obj(1) << endl;

	// 封装仿函数
	Functor fuctor;
	obj = fuctor;

	// 封装类的成员函数和类的静态成员函数
	CTest t;
	// 绑定类的成员函数,一定要传递对象给bind的第二个参数,可以是类对象,也可以是类对象的指针(这是因为成员函数有一个默认的this指针)
	obj = std::bind(&CTest::Func, &t, placeholders::_1);
	cout << "成员函数函数:" << obj(3) << endl;

	// 绑定静态的成员函数
	obj = CTest::SFunc;
	cout << "静态成员函数函数:" << obj(4) << endl;
}

案例2:定义一个 function类型,并作为形参传入类的成员函数,从Function 包装的:函数对象,全局函数,lambda表达式,函数指针这几种方式中,找到一种方式:满足形参赋值给类的成员变量 ------》(先说结论:只有lambda表达式可以实现:捕获对象,从而实现修改类的成员变量)

// main.cpp

#include "test.h"
#include<iostream>
#include<string>
#include<Functional>
using namespace std;

void MyTest::test(callback_ callback) {
	cout << "test call m_i = " << this->m_i << endl;
}

// 全局函数
void func(int i) {
	cout << "global func call m_i = " << i<< endl;
}

// lambda表达式
void lambda() {
	MyTest mytest;
	// lambda表达式:捕获对象 mytest引用,修改成员变量: m_i
	auto lambda = [&mytest](int i) {
		mytest.m_i = i;
		cout << "lambda 本体调用后 m_i = " << mytest.m_i << endl;
	};
	lambda(1);
	mytest.test(lambda);
	cout << "mytest m_i = " << mytest.m_i << endl;
}

// 函数对象(仿函数)
class FunObj
{
public:
	void operator()(int i) {
		cout << "func obj call m_i = " << i << endl;
	}
};

// 函数指针
void (*fun_pointer)(int i);

int main() {
	// lambda 方式:可以捕获当前对象,通过当前对象修改类的成员变量
	// lambda();

	// 全局函数方式(失败,由于function定义的是接收一个参数)(且不能 捕获当前对象,就不能通过当前对象修改类的成员变量)
	/*MyTest mytest1;
	callback_   _callback = func;
	_callback(1);
	mytest1.test(_callback);*/

	// 仿函数的方式(失败,由于function定义的是接收一个参数)(且不能 捕获当前对象,就不能通过当前对象修改类的成员变量)
	/*MyTest test;
	callback_   _callback = FunObj();
	_callback(1);
	test.test(_callback);*/

	// 函数指针方式 (待定)
	MyTest test1;
	callback_   _callback = fun_pointer;
	// _callback(1);
	// fun_pointer(1);
	test1.test(_callback);
}
// test.h


#pragma once
#include<functional>

using callback_ = std::function<void(int)>;
class MyTest
{
public:
	int m_i = 0;
	void test(callback_ callback);
private:

};

三:Functional原理 

猜你喜欢

转载自blog.csdn.net/u013620306/article/details/128067077