我是靠谱客的博主 高挑棒球,最近开发中收集的这篇文章主要介绍C/C++ Lambda表达式概述基本概述:基本形式:,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

基本概述:

关于Lambda表达式之前接触过,但是没有系统总结过,这里整一个基础版的总结;

关于lambda表达式,可以看作三种函数调用形式的最高级别;

之前接触过:函数指针、仿函数;

lambda可以看作仿函数的升级版;

例如其他blog举例:

class Plus {
public:
int operator()(int a, int b) {
return a + b;
}
};

相比于函数指针,更容易在类内保留信息和状态,并且调用和函数类似,原因是重载了"()"操作符:

Plus plus;
std::cout << plus(11, 22) << std::endl;
// 输出 33

对于lambda而言,可以看作仿函数的升级版本;

其实对于编译器的实现而言,其本质上也是隐式构造了一个函数体,例如:

auto plus = [] (int a, int b) -> int { return a + b; }
int c = plus(1, 2);

则编译器则会将表达式翻译为:

class LambdaClass
{
public:
int operator () (int a, int b) const
{
return a + b;
}
};
LambdaClass plus;
int c = plus(1, 2);

可以看到其实就是仿函数的一种特例而已;

基本形式:

lamda表达式具体形式如下所示:

[ capture-list ] ( params ) mutable(optional) exception(optional) attribute(optional) -> ret(optional) { body };

其中exception、attribute目前先不说,后续遇到在补充;

其中ret为指定的返回形式,这里通常可以省略;

capture-list:

捕获列表主要讲述内部所需要的值是如何捕获的;

[] 什么也不捕获,无法lambda函数体使用任何

[=] 按值的方式捕获所有变量

[&] 按引用的方式捕获所有变量

[=, &a] 除了变量a之外,按值的方式捕获所有局部变量,变量a使用引用的方式来捕获。这里可以按引用捕获多个,例如 [=, &a, &b,&c]。这里注意,如果前面加了=,后面加的具体的参数必须以引用的方式来捕获,否则会报错。

[&, a] 除了变量a之外,按引用的方式捕获所有局部变量,变量a使用值的方式来捕获。这里后面的参数也可以多个,例如 [&, a, b, c]。这里注意,如果前面加了&,后面加的具体的参数必须以值的方式来捕获。

[a, &b] 以值的方式捕获a,引用的方式捕获b,也可以捕获多个。

[this] 在成员函数中,也可以直接捕获this指针,其实在成员函数中,[=]和[&]也会捕获this指针。

其中,也可以给捕获的值进行列表初始化,即进行重命名;
例如:

// 按值捕获 target,但是在 Lambda 内部的变量名叫做 v
auto cnt =
std::count_if(books.begin(), books.end(), [v = target](const Book& book) {
return book.title.find(v) != std::string::npos;
});
// 按引用捕获 target,但是在 Lambda 内部的名字叫做 r
auto cnt =
std::count_if(books.begin(), books.end(), [&r = target](const Book& book) {
return book.title.find(r) != std::string::npos;
});

也可以进行右值捕获,用于捕获“Move-only”对象,原因是"Move-only"对象无法进行引用或者复制捕获:

std::unique_ptr<int> uptr = std::make_unique<int>(123);
auto callback = [&uptr]() {
std::cout << *uptr << std::endl;
};

也可以进行指针捕获:

auto cnt =
std::count_if(books.begin(), books.end(), [p = &target](const Book& book) {
return book.title.find(*p) != std::string::npos;
});

表达式主体以及形式:

表达式主体可以直接按照函数形式进行书写,但是要注意一下啊值捕获的问题;

值捕获生成的类形式为:

auto plus = [=] (int a, int b) -> int { return x + y + a + b; };
//翻译为:
class LambdaClass
{
public:
LambdaClass(int xx, int yy)
: x(xx), y(yy) {}
int operator () (int a, int b) const
{
return x + y + a + b;
}
private:
int x;
int y;
}
int x = 1; int y = 2;
LambdaClass plus(x, y);
int c = plus(1, 2);

其中可以看到,符号运算函数为const函数,标志无法在内部进行值修改;

并且值得注意的是,捕获的值作为成员,私有持有,并且传入参数为运算符重载传入的参数;

为了避免这种情况,可以加上mutable关键字;

auto plus = [=] (int a, int b) mutable -> int { x++; return x + y + a + b; };

相应的,对于引用捕获,可以翻译为:

auto plus = [&] (int a, int b) -> int { x++; return x + y + a + b;};
//翻译形式为:
class LambdaClass
{
public:
LambdaClass(int& xx, int& yy)
: x(xx), y(yy) {}
int operator () (int a, int b)
{
x++;
return x + y + a + b;
}
private:
int &x;
int &y;
};

最后

以上就是高挑棒球为你收集整理的C/C++ Lambda表达式概述基本概述:基本形式:的全部内容,希望文章能够帮你解决C/C++ Lambda表达式概述基本概述:基本形式:所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部