首页 > 编程语言 >现代C++(Modern C++)基本用法实践:二、Lambda表达式

现代C++(Modern C++)基本用法实践:二、Lambda表达式

时间:2023-07-13 13:01:48浏览次数:39  
标签:return LOG int auto Modern C++ VAR lambda Lambda

概述

lambda表达式,有时也被称为匿名函数。他提供了简短的,内联的函数对象。用法形式如:

[capture](parameters) -> return_type { body }

具体用法如下文举例

它的实现是由编译器决定的,在我的编译器上他是通过创建一个匿名类,通过重载()运算符,成为一个可调用对象,从而实现调用,类似:

// Lambda表达式
auto lambda = [](int x, int y) { return x + y; };

// 编译器生成的匿名类的简化结构
class __lambda_1 {
public:
    int operator()(int x, int y) const {
        return x + y;
    }
};

用法举例

参考测试项目代码ModernCppTest/modrenc_lambda.cpp
主要内容:

  • 基本用法
  • 参数捕获:值传递/引用传递
  • 捕获this时注意作用域
  • std::function 捕获
  • std::bind绑定对象的成员函数
  • 模板lambda(c++ 20)
#include "ModernCppTestHeader.h"
#include <functional>

using std::function;
using std::bind;

namespace n_lambda {
	class Class1
	{
	public:
		auto F() 
		{ 
			return [this]() {return val; };
		};

		int val = 123;
	};

	class Class2
	{
	public:

		int F(int x) { return a + x; };
	private:
		int a = 10;
	};
}

void lambda_test()
{
	LOG_FUNC();

	LOG_TAG("常用");
	{
		auto f = [](auto a, auto b) {return a + b; };
		int v = f(1, 2);
		LOG_VAR(v);
	}

	LOG_TAG("C++14 默认实参");
	{
		auto f = [](auto a, int b = 10) {return a + b; };
		auto v = f(5);
		LOG_VAR(v);
	}


	LOG_TAG("被std::function捕获 (会带来一些开销)");
	{
		function<int(int, int)> f = [](int a, int b) {return a + b; };
		auto v = f(3, 4);
		LOG_VAR(v);
	}


	LOG_TAG("捕获参数");
	{
		int a = 1;
		int b = 2;
		int c = 3;

		auto f1 = [=]() {return a + b; };
		auto f2 = [&]() {return a + b; };
		auto f3 = [&b, c](int x) {return x + b + c; };

		b = 12;
		c = 13;

		auto v1 = f1();
		LOG_VAR_DESC(v1, "[=]拷贝全部");

		auto v2 = f2();
		LOG_VAR_DESC(v2, "[&]引用全部");

		auto v3 = f3(1);
		LOG_VAR_DESC(v3, "一个引用, 一个拷贝");
	}


	LOG_TAG("this作用域测试");
	{
		function<int()> f;
		{
			n_lambda::Class1 t;
			f = t.F();
			int v = f();
			LOG_VAR_DESC(v, "t 对象在作用域{}内, 正确");
		}
		int v = f();
		// 注意,有可能值是对的,根据切豆腐理论,如果t对象的生命周期结束了,但是未被内存管理回收,那么它依然可以使用
		LOG_VAR_DESC(v, "t 对象在作用域{}外, 导致lambda捕获的this指针空悬,未定义行为,值有可能出错");
	}


	LOG_TAG("使用bind绑定对象的成员函数到function对象");
	{
		n_lambda::Class2 t;
		function<int(int)> f = bind(&n_lambda::Class2::F, &t, std::placeholders::_1);
		int v = f(5);
		LOG_VAR(v);
	}


	LOG_TAG(" 【C++ 20】 模板 lambda");
	{
		auto f = []<class T> (T t) { LOG_VAR(t); };
		f(1);
		f(1.25f);
	}
}

标签:return,LOG,int,auto,Modern,C++,VAR,lambda,Lambda
From: https://www.cnblogs.com/hggzhang/p/17523875.html

相关文章

  • 现代C++(Modern C++)基本用法实践:七、范围遍历
    概述c++的for循环在语法上有些刻板,近几个版本对此进行了优化,支持了基于范围的for循环用法举例参考测试项目代码ModernCppTest/modrenc_range_for.cpp主要内容:数组遍历vector遍历字符串遍历map遍历#include"ModernCppTestHeader.h"#include<vector>#include<map>......
  • 现代C++(Modern C++)基本用法实践:六、constexpr编译时计算
    概述constexpr修饰的变量、函数、对象构造函数表示在编译时就可以确定。它经常用来计算一些编译期可以确定常数,和常数组成的表。比如编译时确定10000以内所有的素数,运行时用的时候直接查表。用法举例参考测试项目代码ModernCppTest/modrenc_constexpr.cpp主要内容:constexpr......
  • 现代C++(Modern C++)基本用法实践:零、概述&测试项目
    序言习惯上,我们把C++11之前的C++语法特性称之为“传统C++”,而把c++11之后的语法特性称之为现代C++。有一种说法称C++为中级语言,因为它的特性介于低级语言(如各类汇编语言)和高级语言(Python、C#)之间--一般来说,它在运行效率上比高级语言要高,而在开发效率上又比高级语言低一些。随着C......
  • 现代C++(Modern C++)基本用法实践:N、其他零散的常用特性
    概述这一篇简单介绍一些其他的比较实用的特性,如果读者想了解现代C++的全部特性,参考:cppreference其他特性预置和弃置函数default&delete在C++11中引入了default和delete关键字,允许程序员更加明确地控制类的默认操作(如默认构造函数,拷贝构造函数,拷贝赋值运算符,析构函数等)......
  • 现代C++(Modern C++)基本用法实践:八、线程支持
    概述在c++11之前,c++并未对线程编程提供直接的支持。在c++11之后,支持了线程管理、同步、条件变量等支持。在其他的c++库中(例如UE的线程库)还增加了多任务模型的抽象。用法举例参考测试项目的modrenc_auto_decltype.cpp文件主要内容:线程的创建使用future&async进行异步操作......
  • PAT-甲级-1007 Maximum Subsequence Sum C++
    Givenasequenceof K integers{ N1​, N2​,..., N​K }.Acontinuoussubsequenceisdefinedtobe{ Ni​, Ni+1​,..., Nj​ }where 1≤i≤j≤K.TheMaximumSubsequenceisthecontinuoussubsequencewhichhasthelargestsumofitselements.Fore......
  • c++ day 8
    今天终于来学习时间复杂度了当分析算法的时间复杂度时,我们通常关注以下几个方面来确定算法的执行时间:循环次数:循环是算法中常见的结构,它会重复执行一段代码。时间复杂度取决于循环的次数。例如,一个循环从1到n的遍历,时间复杂度就是O(n)。嵌套循环:如果算法中存在多个嵌套循环......
  • 【C++开源库】Windows 下编译 libcurl 库
    Whatislibcurl?libcurl是一个跨平台的网络协议库,支持http,https,ftp,gopher,telnet,dict,file,和ldap协议。libcurl同样支持HTTPS证书授权,HTTPPOST,HTTPPUT,FTP上传,HTTP基本表单上传,代理,cookies和用户认证。想要知道更多关于libcurl的介绍,可以到官网......
  • C++ 数据封装
     所有的C++程序都有以下两个基本要素:程序语句(代码):这是程序中执行动作的部分,它们被称为函数。程序数据:数据是程序的信息,会受到程序函数的影响。封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全。数据封装......
  • C++ 接口(抽象类)
     接口描述了类的行为和功能,而不需要完成类的特定实现。C++接口是使用抽象类来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念。如果类中至少有一个函数被声明为纯虚函数,则这个类就是抽象类。https://www.lekaowang.com/cfa/oitt/......