服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++详细分析lambda表达式的本质

C++详细分析lambda表达式的本质

2023-02-09 15:58配的上了吗 C/C++

Lambda表达式是现代C++在C ++ 11和更高版本中的一个新的语法糖 ,在C++11、C++14、C++17和C++20中Lambda表达的内容还在不断更新。 lambda表达式(也称为lambda函数)是在调用或作为函数参数传递的位置处定义匿名函数对象的便捷方法

例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
stable_sort(words.begin(), words.end(),
        [](const string& s1, const string& s2)
        { return s1.size() < s2.size(); });
class ShorterString
{
public:
    bool operator()(const string& s1,const string& s2)const
    {
        return s1.size() < s2.size();
    }
};
// 等价于
stable_sort(words.begin(), words.end(), ShorterString();
// 或者
ShorterString s;
stable_sort(words.begin(), words.end(), s;

写一个lambda表达式之后,编译器将该表达式翻译为一个未命名类的未命名对象。

且lambda表达式产生的类中含有一个重载的函数调用运算符。且该函数调用运算符成员的形参列表和函数体与lambda表达式完全一样。

此时,stable_sort的内部代码每次比较两个string时就会"调用"这一对象。此对象将会调用运算符的函数体,返回true or false

我们知道,lambda表达式可以捕获变量,且分为引用捕获和值捕获,而当引用捕获时,由程序负责确保lambda执行时引用所引的对象确实存在,而编译器就会直接使用该引用,无需在lambda产生的类中将其存储为数据成员

根据上一段话的介绍,大致也可以猜想出,若采用值捕获的方式,被值捕获的变量会被拷贝至lambda中。因此,这种lambda产生的类必须为每个值捕获的变量创建对应的数据成员。 同时创建构造函数。令其使用捕获的变量的值来初始化数据成员。

默认情况下lambda表达式不可以改变它捕获的变量。所以重载函数调用运算符的函数默认情况下会被定义为const。

举例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
auto wc = find_if(words.begin(), words.end(),
    [sz] (const string& s) { return s.size() >= sz; } );
class Sizecomp
{
public:
    Sizecomp(size_t n) :sz(n) {}
    bool operator()(const string& s)const
    {
        return s.size() >= sz;
    }
private:
    size_t sz;
};
// 等价于
auto wc = find_if(words.begin(), words.end(), Sizecomp(sz));

此类无默认构造函数,因此要想使用这个类必须提供一个实参。数据成员sz对应通过值捕获的变量。用此值捕获变量的值来初始化该sz数据成员。

在C++11中, lambda是通过匿名的函数对象来实现的,因此我们可以把lambda看作是对函数对象在使用方式上进行的简化。

当代码需要一个简单的函数,并且这个函数并不会在其他地方被使用时,就可以使用lambda来实现,此时它所起的作用类似于匿名函数。 但如果这个函数需要多次使用,并且它需要保存某些状态的话,使用函数对象则更合适一些。

练习:编写程序,统计一个vector<string>中元素size处于1-9的有几个,大于等于10的有几个

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class StrLenBetween
{
public:
    StrLenBetween(int m, int x) :min(m), max(x) {}
    bool operator()(const string& s)const
    {
        return s.size() >= min && s.size() <= max;
    }
private:
    int min;
    int max;
};
void readStr(istream& is, vector<string>& v)
{
    string s;
    while (is >> s)
        v.push_back(s);
}
int main()
{
    vector<string> vec;
    readStr(cin, vec);
    const int min = 1;
    const int max = 10;
    cout << "len 1~9 : " << count_if(vec.begin(), vec.end(), [min, max](const string& s)->bool {return s.size() >= 1 && s.size() <= 9; }) << endl;
    cout << "len >= 10 : " << count_if(vec.begin(), vec.end(), [max](const string& s)->bool {return s.size() >= max; }) << endl;
    cout << "len 1~9 : " << count_if(vec.begin(), vec.end(), StrLenBetween(min, max)) << endl;
    return 0;
}

主函数第一个cout和第三个cout意义相同。

到此这篇关于C++详细分析lambda表达式的本质的文章就介绍到这了,更多相关C++lambda表达式内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/i777777777777777/article/details/124899838

延伸 · 阅读

精彩推荐
  • C/C++C++广播通信实例

    C++广播通信实例

    这篇文章主要介绍了C++实现广播通信的方法,实例讲述了C++ socket广播通信的原理与实现方法,需要的朋友可以参考下...

    C++教程网7272021-02-14
  • C/C++C语言实现的猜拳游戏代码分享

    C语言实现的猜拳游戏代码分享

    本文给大家分享的是一个C语言实现的猜拳小游戏,由于本程序简单易操作,交互性好,对用户没什么特别要求。这里推荐给大家...

    C语言教程网5162021-03-25
  • C/C++一起来学习C++的动态内存管理

    一起来学习C++的动态内存管理

    这篇文章主要为大家详细介绍了C++的动态内存管理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你...

    月半木斤9832022-11-01
  • C/C++C语言入门的一些基本资源推荐和程序语法概览

    C语言入门的一些基本资源推荐和程序语法概览

    这篇文章主要介绍了C语言入门的一些基本资源推荐和程序语法概览,C语言是很多现代高级编程语言的基础,需要的朋友可以参考下...

    C语言教程网4672021-03-17
  • C/C++嵌入式C实战项目开发技巧:对一个有规律的数组表进行位移操作的方法

    嵌入式C实战项目开发技巧:对一个有规律的数组表进行位移操作

    今天小编就为大家分享一篇关于嵌入式C实战项目开发技巧:对一个有规律的数组表进行位移操作的方法,小编觉得内容挺不错的,现在分享给大家,具有很...

    Engineer-Bruce_Yang11602021-07-14
  • C/C++C语言实现3个数从小到大排序/输出的方法示例

    C语言实现3个数从小到大排序/输出的方法示例

    这篇文章主要给大家介绍了关于如何利用C语言实现3个数从小到大排序/输出的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C语言具有...

    Linux公社4272021-07-29
  • C/C++浅谈带缓冲I/O 和不带缓冲I/O的区别与联系

    浅谈带缓冲I/O 和不带缓冲I/O的区别与联系

    下面小编就为大家带来一篇浅谈带缓冲I/O 和不带缓冲I/O的区别与联系。小编觉得挺不错的现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    C语言教程网7722021-04-26
  • C/C++VS2019开发Linux C++程序的实现步骤

    VS2019开发Linux C++程序的实现步骤

    由于很多unix特有的函数无法在Windows上使用,而Vim又用的不太顺手,突然想到最初用vs的时候有一个基于Linux的C++开发。本文就来介绍一下,感兴趣的可以了...

    Respect@6622021-11-25