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