IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ lambda表达式的实质:一个未命名类的未命名函数对象 -> 正文阅读

[C++知识库]C++ lambda表达式的实质:一个未命名类的未命名函数对象

例:

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。

举例:

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的有几个

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++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-24 17:55:54  更:2022-05-24 17:56:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/14 4:25:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码