我是靠谱客的博主 可靠过客,最近开发中收集的这篇文章主要介绍c++ lamber表达式前言一、lamber是什么?二、举例总结,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 前言
  • 一、lamber是什么?
  • 二、举例
  • 总结


前言

template<class T>
struct Greater
{
bool operator()(const T& x1, const T& x2)
{
return x1 > x2;
}
};
bool g2(const int& x1, const int& x2)
{
return x1 > x2;
}
int x4()
{
int array[] = { 4, 1, 8, 5, 3, 7, 0, 9, 2, 6 };
// 默认按照小于比较,排出来结果是升序
std::sort(array, array + sizeof(array) / sizeof(array[0]));
// 如果需要降序,需要改变元素的比较规则
//std::sort(array, array + sizeof(array) / sizeof(array[0]), greater<int>());
Greater<int> g1;
g1(1, 2); // g1是一个对象,这里调用的是他的operator()实现的比较
g2(1, 2); // g2是一个函数指针,这里是调用他指向的函数
// 他们是完全不同的对象但是他们用起来是一样的。
std::sort(array, array + sizeof(array) / sizeof(array[0]), g1);
std::sort(array, array + sizeof(array) / sizeof(array[0]), g2);
return 0;
}
struct Goods
{
string _name;
// 名字
double _price; // 价格
int
_num;
// 数量
// ...
};

那么这里如果去重载Goods的operator>/operator<是不好的,因为你不知道需要按哪一项成员去比较,所以这里用到lamber表达式就很方便

一、lamber是什么?

ambda表达式书写格式:[capture-list] (parameters) mutable -> return-type { statement }

  1. lambda表达式各部分说明
    [capture-list] : 捕捉列表,该列表总是出现在lambda函数的开始位置,编译器根据[]来判断接下来的代码是否为lambda函数,捕捉列表能够捕捉上下文中的变量供lambda函数使用。
    (parameters):参数列表。与普通函数的参数列表一致,如果不需要参数传递,则可以连同()一起省略
    mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常量性。使用该修饰符时,参数列表不可省略(即使参数为空)。
    ->returntype:返回值类型。用追踪返回类型形式声明函数的返回值类型,没有返回值时此部分可省略。返回值类型明确情况下,也可省略,由编译器对返回类型进行推导。
    {statement}:函数体。在该函数体内,除了可以使用其参数外,还可以使用所有捕获到的变量。
    注意: 在lambda函数定义中,参数列表和返回值类型都是可选部分,而捕捉列表和函数体可以为空。
    因此C++11中最简单的lambda函数为:[]{}; 该lambda函数不能做任何事情。
    lambda表达式实际上可以理解为无名函数,该函数无法直接调用,如果想要直接调用,可借助auto将其赋值给一个变量。
auto fun1 = [&](int c){b = a + c; };
fun1(10)
cout<<a<<" "<<b<<endl;
  1. 捕获列表说明
    捕捉列表描述了上下文中那些数据可以被lambda使用,以及使用的方式传值还是传引用。
    [var]:表示值传递方式捕捉变量var
    [=]:表示值传递方式捕获所有父作用域中的变量(包括this)
    [&var]:表示引用传递捕捉变量var
    [&]:表示引用传递捕捉所有父作用域中的变量(包括this)
    [this]:表示值传递方式捕捉当前的this指针

举例:[=, &a, &b]:以引用传递的方式捕捉变量a和b,值传递方式捕捉其他所有变量 [&,a, this]:值
传递方式捕捉变量a和this,引用方式捕捉其他变量 c. 捕捉列表不允许变量重复传递,否则就会导致编
译错误。 比如:[=, a]:=已经以值传递方式捕捉了所有变量,捕捉a重复
传值补充的对象是不能被改变的。(加上mutable就可以改变了)

二、举例

struct Goods
{
string _name;
// 名字
double _price; // 价格
int
_num;
// 数量
// ...
};
struct ComparePriceGreater
{
bool operator()(const Goods& gl, const Goods& gr)
{
return gl._price > gr._price;
}
};
struct CompareNumGreater
{
bool operator()(const Goods& gl, const Goods& gr)
{
return gl._num > gr._num;
}
};
struct CompareNameGreater
{
bool operator()(const Goods& gl, const Goods& gr)
{
return gl._name > gr._name;
}
};
int main()
{
Goods gds[] = { { "苹果", 2.1, 3 }, { "香蕉", 3.0, 5 }, { "橙子", 2.2, 9 }, { "菠萝", 1.5, 10 } };
sort(gds, gds + sizeof(gds) / sizeof(gds[0]), ComparePriceGreater());
sort(gds, gds + sizeof(gds) / sizeof(gds[0]), CompareNumGreater());
sort(gds, gds + sizeof(gds) / sizeof(gds[0]), CompareNameGreater());
// lamber优势就会让代码可读性更强
/*auto price_greater = [](const Goods& g1, const Goods& g2)->bool{return g1._price > g2._price; };
sort(gds, gds + sizeof(gds) / sizeof(gds[0]), price_greater);
*/
sort(gds, gds + sizeof(gds) / sizeof(gds[0]), [](const Goods& g1, const Goods& g2)->bool{return g1._price > g2._price; });
sort(gds, gds + sizeof(gds) / sizeof(gds[0]), [](const Goods& g1, const Goods& g2)->bool{return g1._price < g2._price; });
sort(gds, gds + sizeof(gds) / sizeof(gds[0]), [](const Goods& g1, const Goods& g2)->bool{return g1._num > g2._num; });
sort(gds, gds + sizeof(gds) / sizeof(gds[0]), [](const Goods& g1, const Goods& g2)->bool{return g1._num < g2._num; });
return 0;
}

总结

底层还是依靠仿函数来实现,也就是说你定义了一个lamber表达式,
实际上编译器会全局域生成一个叫lamber_uuid类,仿函数的operator()的参数和实现
就是我们写的labmber表达式的参数和实现

int main()
{
int a = 1, b = 2;
//
对象 = 对象(替换编译器生成的lamber_uuid仿函数的对象)
auto add = [](int x, int y)->int{return x + y; };
add(a, b);
// call lamber_uuid仿函数的operator()
// 底层还是依靠仿函数来实现,也就是说你定义了一个lamber表达式,
// 实际上编译器会全局域生成一个叫lamber_uuid类,仿函数的operator()的参数和实现
// 就是我们写的labmber表达式的参数和实现
/*
00A5C8AC
mov
eax, dword ptr[b]
00A5C8AF
push
eax
00A5C8B0
mov
ecx, dword ptr[a]
00A5C8B3
push
ecx
00A5C8B4
lea
ecx, [add]
00A5C8B7
call
<lambda_afc2b2a8543babab622761003a6aa683>::operator() (0A5AEC0h)
*/
auto swapab = [&a, &b](){
int c = a;
a = b;
b = c;
};
swapab();
/*
0065DA4C
lea
ecx, [swapab]
0065DA4F
call
<lambda_574e874b35e37ce2b7269242f59eb074>::operator() (065ADC0h)
*/
return 0;
}

最后

以上就是可靠过客为你收集整理的c++ lamber表达式前言一、lamber是什么?二、举例总结的全部内容,希望文章能够帮你解决c++ lamber表达式前言一、lamber是什么?二、举例总结所遇到的程序开发问题。

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

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

评论列表共有 0 条评论

立即
投稿
返回
顶部