简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
1.前言
本篇目的:std::function总结
2.概念
1. 什么是闭包?
闭包(Closure)是指一个函数捕获并保存了其所在上下文中的变量,即使这些变量在函数执行完毕后也依然可以访问和操作。换句话说,闭包允许一个函数访问其词法作用域外部的变量。
在C++中,闭包通常是通过lambda表达式来实现的。Lambda表达式是一种能够定义匿名函数的方式。它可以捕获当前作用域内的变量,并作为函数对象来调用。
函数指针(Function Pointer)是指一个指向函数的指针变量。可以将函数指针作为参数传递给其他函数,也可以将函数指针作为函数的返回值。
通过使用函数指针,我们可以在运行时动态选择调用的函数。这在编写库、插件等灵活可扩展的程序中非常有用。函数指针还可以用于实现回调函数,即将一个函数作为参数传递给另一个函数,在特定事件发生时被调用。
使用函数指针时,需要注意函数的签名(返回类型和参数列表)。函数指针类型必须与被指向的函数的签名相匹配,否则会导致编译错误。
总结来说,闭包是一种可以捕获外部上下文的函数对象,而函数指针是指向函数的指针变量,可以作为参数传递或者在运行时动态选择调用的函数。
2. 什么是仿函数?
仿函数(Functor)是一种可以像函数一样被调用的对象,在C++中常用于函数对象的实现。它是一个类或结构体,重载了函数调用运算符 operator()。通过在代码中创建并使用仿函数对象,我们可以实现自定义的函数行为和操作。
仿函数可以具有多种形式,可以是普通函数指针、类成员函数指针、函数对象或Lambda表达式。它们可以像函数一样被调用,并接受参数进行处理。因此,在使用仿函数时,可以将其视为可调用的函数对象,具有函数的行为和特性。
显示如何定义和使用一个仿函数
#include <iostream>
// 定义一个加法仿函数
struct AddFunctor {
int operator()(int a, int b) const {
return a + b;
}
};
int main() {
AddFunctor add; // 创建一个AddFunctor对象
int result = add(5, 3); // 调用仿函数对象,相当于调用add.operator()(5, 3)
std::cout << "Result: " << result << std::endl;
return 0;
}
总结起来,仿函数是一种可调用的对象,可以像函数一样被调用,并具有函数的行为和特性。它是C++中实现函数对象的一种机制,可以用来实现各种灵活的函数行为和操作。
3.function支持对四种函数的封装
function定义通用公式:
std::function<返回类型(参数类型)> 函数对象;
std::function可以封装的几种常见类型的可调用对象
- 函数指针:
int add(int a, int b) {
return a + b;
}
std::function<int(int, int)> func = add;
func(10,20);
- 函数对象(仿函数):
struct Multiply {
int operator()(int a, int b) const {
return a * b;
}
};
std::function<int(int, int)> func = Multiply();
func(100,200);
- 成员函数指针:
class Math {
public:
int multiply(int a, int b) {
return a * b;
}
};
Math math;
std::function<int(Math*, int, int)> func = &Math::multiply;
func(100,200);
- Lambda 表达式:
std::function<int(int, int)> func = [](int a, int b) {
return a + b;
};
3.应用实例
#include <functional>
#include <iostream>
using namespace std;
int test (int n) {
printf("line = %d, n = %d\n",__LINE__,n);
return n;
}
class A {
public:
A(){};
int B(int n) {
printf("line = %d, n = %d\n",__LINE__,n);
return n;
}
int operator() (int n) {
printf("line = %d, n = %d\n",__LINE__,n);
return n;
}
};
int main () {
test(123);
//普通函数
std::function<int (int)> f1 = test;
f1(456);
//匿名函数
std::function<int (int)> f2 = [](int n)->int {
printf("line = %d, n = %d\n",__LINE__,n);
return n;
};
f2(789);
//类的成员函数,因为类的成员函数默认会传递该对象的this指针,所以需要写出&A
std::function<int(A&,int)> f3 = &A::B;
A a;
f3(a,10001);
//仿函数
std::function<int (A&, int)> f4 = &A::operator();
A b;
f4(b,123);
return 0;
}