简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
1.前言
本篇目的:理解C++之lambda匿名函数、typedef、using等用法
2.C++之lambda匿名、using、typedef介绍
1.lambda介绍
- Lambda函数是一种匿名函数,可以在C++中使用。它提供了一种简洁的方式来定义和使用临时的函数对象。Lambda函数通过使用方便的语法来简化函数对象的创建过程,使代码更加简洁和易读。
Lambda函数的基本语法如下:
[capture list] (parameters) -> return_type { function_body }
- Capture列表:指定Lambda函数所捕获的外部变量。它可以是值捕获(通过值进行拷贝)或引用捕获(通过引用进行访问)的方式。
- 参数列表:指定Lambda函数的参数。
- 返回类型:指定Lambda函数的返回类型(可以省略,编译器会自动推断)。
- 函数体:实现Lambda函数的具体逻辑。
3.lambda匿名、using、typedef介绍
- Lambda匿名函数:
Lambda函数是一种匿名函数,允许我们在需要函数对象的地方定义临时的、即时的函数逻辑。它的语法如下:
[capture list] (parameters) -> return_type { function_body }
- Capture列表(可选): 指定Lambda函数所捕获的外部变量。
- 参数列表: 指定Lambda函数的参数。
- 返回类型(可选): 指定Lambda函数的返回类型。如果不指定,则编译器会自动推断。
- 函数体: 实现Lambda函数的具体逻辑。
Lambda函数可以用于算法函数、STL容器的处理、回调函数等地方,可以使代码更加简洁和易读。
- using声明:
Using声明在C++中用来引入一个特定的类型或命名空间,以便在当前作用域中使用。它的语法如下:
using name = type;
这里的name
是我们定义的别名,type
是需要引入的类型。
Using声明可以用来简化复杂的类型名称,或者引入命名空间中的类型。例如:
using IntVector = std::vector<int>;
IntVector numbers = {1, 2, 3, 4, 5};
这里,我们使用了using
声明引入了std::vector<int>
类型的别名IntVector
,从而将其简化为更易读的名称。
- typedef声明:
Typedef声明也是用来引入一个特定的类型别名,以便在当前作用域中使用。它的语法如下:
typedef type name;
这里的type
是我们需要引入的类型,name
是我们定义的别名。
Typedef声明的作用和using声明类似,它也可以用来简化复杂的类型名称。例如:
typedef std::vector<int> IntVector;
IntVector numbers = {1, 2, 3, 4, 5};
这里,我们使用了typedef声明将std::vector<int>
类型定义为IntVector,从而使代码更加易读。
总结:
Lambda函数提供了一种简洁的方式来定义匿名函数,using声明和typedef声明提供了简化类型名称的能力。这些工具可以使代码更加清晰、易读和易于维护。
3.代码实例
v1.0 函数调用实例
#include <iostream>
#include <string>
#include <functional>
typedef std::function<int(int x, int y)> Callback ;
using UCallback = std::function<int(int x, int y)> ;
//v1.0
int call_add(std::function<int(int x, int y)> call){
int a = 100, b=500;
call(a, b);//传值a,b给调用者.
return a+b;
}
//v2.0: 与以上等同:使用typedef定义Callback类型别名定义
int call_add_01(Callback call){
int a = 100, b=500;
call(a, b);//传值a,b给调用者.
return a+b;
}
//v3.0: 与以上等同:使用using定义UCallback类型别名定义
int call_add_02(UCallback call){
int a = 100, b=500;
call(a, b);//传值a,b给调用者.
return a+b;
}
int main() {
//v1.0:匿名lambda函数,无参数,无返回值.
[](){
printf("xxx----->%s(), line = %d\n",__FUNCTION__,__LINE__);
}();
//v2.0:匿名lambda函数,带string参数,无返回值.
[](std::string content){
printf("xxx----->%s(), line = %d, content = %s\n",__FUNCTION__,__LINE__,content.c_str());
}("Hello Wolrd.");
//v3.0:匿名lambda函数,带string和int类型参数,无返回值.
std::string buf = "Hello, C++!";
int year = 2023;
[](std::string buf, int years){
printf("xxx----->%s(), line = %d, buf = %s, years = %d\n",__FUNCTION__,__LINE__,buf.c_str(), years);
}(buf, year);
//v3.1: lambda带返回值
int moth = [](std::string buf, int years){
printf("xxx----->%s(), line = %d, buf = %s, years = %d\n",__FUNCTION__,__LINE__,buf.c_str(), years);
int month = 10;
return month;
}(buf, year);
printf("xxx----->%s(), line = %d, moth = %d\n",__FUNCTION__,__LINE__,moth);
//4.0: 使用typedef创建别名类型Callback,然后调用回调函数.
Callback add = [](int a, int b)->int {
printf("xxx---------->%s(), line = %d, a = %d, b = %d\n",__FUNCTION__,__LINE__,a,b);
return a + b;
};
printf("xxx----->%s(), line = %d, add = %d\n",__FUNCTION__,__LINE__,add(2, 3));
//v5.0: 使用typedef定义回调函数类型别名
int ret1 = call_add(add);
printf("xxx----->%s(), line = %d, ret1 = %d\n",__FUNCTION__,__LINE__,ret1);
//v6.0: 直接使用lambda匿名回调函数
int ret2 = call_add([](int x, int y)->int{
return x + y;
});
printf("xxx----->%s(), line = %d, ret2 = %d\n",__FUNCTION__,__LINE__,ret2);
//v7.0: 使用typedef定义回调函数类型别名
int ret3 = call_add_01(add);
printf("xxx----->%s(), line = %d, ret3 = %d\n",__FUNCTION__,__LINE__,ret3);
//v8.0: 使用using定义回调函数类型别名
int ret4 = call_add_02(add);
printf("xxx----->%s(), line = %d, ret4 = %d\n",__FUNCTION__,__LINE__,ret4);
//v9.0: 直接使用lambda匿名回调函数
int ret5 = call_add_02([](int x, int y)->int{
return x + y;
});
printf("xxx----->%s(), line = %d, ret5 = %d\n",__FUNCTION__,__LINE__,ret5);
return 0;
}
v2.0 类指针、引用、指针的引用实例01
#include <iostream>
#include <string>
#include <memory>
#include <functional>
class TEST{
public:
void log(){
printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}
TEST(){
printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}
TEST(std::shared_ptr<TEST> &test){
printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}
};
//1.typedef定义:typedef 类型 别名.
typedef std::function<void(std::shared_ptr<TEST> &test)> Callback ;
//2.using定义:using 别名 = 类型.
using UCallback = std::function<void(std::shared_ptr<TEST> &test)> ;
void callback_test(std::function<void(std::shared_ptr<TEST> &test)> func){
std::shared_ptr<TEST> tt = std::make_shared<TEST>();
func(tt);
}
int main() {
//v1.0: lambda匿名函数返回指针TEST*类型,无参数
TEST *t1 = [&]()->TEST*{
return new TEST;
}();
t1->log();
//v1.1
TEST *t12 = [&]()->TEST*{
return new TEST;
}();
t12->log();
//2.0: lambda匿名函数返回TEST类型指针对象,无参数
TEST t2 = [&]()->TEST{
return TEST{}; //TEST{}创建对象方式
}();
t2.log();
//v2.1: TEST()创建对象方式
TEST t21 = [&]()->TEST{
return TEST();
}();
t21.log();
//3.0: lambda匿名函数返回TEST类型指针对象,无返回值
TEST *t3;
[&](TEST *tr){
tr = new TEST;
}(t3);
t3->log();
//4.0: lambda匿名函数返回TEST类型指针的引用对象,无返回值
TEST *t4;
[&](TEST* &tr){//指针的引用
tr = new TEST();
}(t4);
t4->log();
//5.0: lambda匿名函数返回TEST类型shared_ptr指针对象,无返回值
std::shared_ptr<TEST> t5;
[&](std::shared_ptr<TEST> tr){//指向TEST类型shared_ptr指针对象
tr = std::make_shared<TEST>();
}(t5);
t5->log();
//6.0: lambda匿名函数返回TEST类型shared_ptr指针的引用对象,无返回值
std::shared_ptr<TEST> t6;
[&](std::shared_ptr<TEST> &tr){//指向TEST类型shared_ptr指针的引用的对象,即make_shared<TEST>()指针对象的别名.
tr = std::make_shared<TEST>();
}(t6);
t6->log();
//7.0: lambda匿名函数返回TEST类型shared_ptr指针的引用对象
std::shared_ptr<TEST> t7;
[&](std::shared_ptr<TEST> &tr)->std::shared_ptr<TEST> {//指向TEST类型shared_ptr指针的引用的对象,即make_shared<TEST>()指针对象的别名.
//tr = std::make_shared<TEST>();
return std::make_shared<TEST>(tr);
}(t7);
t7->log();
//8.0: lambda匿名函数返回TEST类型shared_ptr指针的引用对象,有返回值和参数.
/*t8和t8.get()区别:
t8是一个std::shared_ptr<TEST>类型的共享指针,指向一个TEST对象.
t8.get(): 返回的是一个指向同一对象的原始指针.
*/
std::shared_ptr<TEST> t8;
[&](void* tr) -> std::shared_ptr<TEST> {
return std::make_shared<TEST>(static_cast<TEST*>(tr));
}(t8.get());
t8->log();
//9.0
std::shared_ptr<TEST> t10;
callback_test([&](std::shared_ptr<TEST>& tr) -> void {
t10 = tr;
});
t10->log();
return 0;
}
v3.0 类指针、引用、指针的引用实例02
#include <iostream>
#include <string>
#include <memory>
#include <functional>
class TEST{
public:
void log(){
printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}
TEST(){
printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}
TEST(std::shared_ptr<TEST> &test){
printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}
};
//1.typedef定义:typedef 类型 别名.
typedef std::function<void(std::shared_ptr<TEST> &test)> Callback ;
//2.using定义:using 别名 = 类型.
using UCallback = std::function<void(std::shared_ptr<TEST> &test)> ;
void callback_test(std::function<void(std::shared_ptr<TEST> &test)> func){
std::shared_ptr<TEST> tt = std::make_shared<TEST>();
func(tt);
}
std::shared_ptr<TEST> callback_ret(){
//std::shared_ptr<TEST> tt = std::make_shared<TEST>();
//return tt;
return std::make_shared<TEST>();
}
int main() {
//v1.0
std::shared_ptr<TEST> t1= callback_ret();
t1->log();
//v2.0
std::shared_ptr<TEST> t2;
callback_test([&](std::shared_ptr<TEST> &tr) -> void {
t2 = tr;
});
t2->log();
return 0;
}
C++中shared_ptr和shared_ptr::get()实现
template<typename T>
class shared_ptr {
public:
explicit shared_ptr(T* ptr = nullptr) : ptr_(ptr), ref_count_(new int(1)) {}
~shared_ptr() {
if (--(*ref_count_) == 0) {
delete ptr_;
delete ref_count_;
}
}
shared_ptr(const shared_ptr& other) : ptr_(other.ptr_), ref_count_(other.ref_count_) {
++(*ref_count_);
}
shared_ptr& operator=(const shared_ptr& other) {
if (this != &other) {
if (--(*ref_count_) == 0) {
delete ptr_;
delete ref_count_;
}
ptr_ = other.ptr_;
ref_count_ = other.ref_count_;
++(*ref_count_);
}
return *this;
}
T* get() const {
return ptr_;
}
private:
T* ptr_; // 指向所管理的对象的原始指针
int* ref_count_; // 引用计数,记录共享此对象的智能指针数量
};
shared_ptr类维护了一个指针ptr_和一个计数器ref_count_。每当有新的shared_ptr指向相同的对象时,ref_count_会递增。当没有shared_ptr指向该对象时,ref_count_会减少并在变为零时释放资源。
get()函数的实现非常简单,它只需返回私有成员ptr_,即所管理的对象原始指针。