C++ Lambda表达式第一篇, 闭合(Closuretype)
C++ Lambda表达式第一篇, 闭合Closuretype
- ClosureType::operator()(params)
- auto 模板参数类型
- 显式模板参数类型
- 其他
- ClosureType::operator ret(*)(params)()
lambda 表达式是唯一的未命名,非联合,非聚合类类型(称为闭包类型)的纯右值表达式,它在包含 lambda 的最小块作用域、类作用域或命名空间作用域中声明(出于 ADL 的目的)表达。
当且仅当 captures 为空时,闭包类型才是结构类型。
闭包类型具有以下成员,它们不能显式实例化、显式专门化或在友元声明中命名:
ClosureType::operator()(params)
ret operator()(params) { body }
template<template-params>
ret operator()(params) { body }
调用时,执行 lambda 表达式的主体。访问变量时,访问其捕获的副本(对于通过副本捕获的实体)或原始对象(对于通过引用捕获的实体)。
如果提供了operator()的参数列表,则为params,否则参数列表为空。
operator()的返回类型是trailing-type中指定的类型。
如果未提供 Trailing-type,则自动推导出operator() 的返回类型。
除非在 lambda 说明符中使用关键字 mutable,或者存在显式对象参数,否则 operator() 的 cv 限定符为 const,并且通过 copy 捕获的对象从内部不可修改这个运算符()。不允许显式 const 限定符。 operator() 从来都不是虚拟的,并且不能具有 volatile 限定符。
- 如果operator() 满足constexpr 函数的要求,则它始终是constexpr。如果 lambda 说明符中使用了关键字 constexpr,那么,它也是 constexpr。
- 如果 lambda 说明符中使用了关键字 consteval,则operator() 是立即函数。
- 如果 lambda 说明符中使用了关键字 static,则operator() 是静态成员函数。
- 如果 params 包含显式对象参数,则operator() 是显式对象成员函数。
auto 模板参数类型
对于 params 中类型指定为 auto 的每个参数,都会按照出现的顺序将发明的模板参数添加到 template-params 中。如果params对应的函数成员是函数参数包,则本发明的模板参数可以是参数包。
#include <iostream>
#include <iostream>
#include <fstream>using namespace std;// generic lambda, operator() is a template with two parameters
auto glambda = [](auto a, auto&& b) { return a < b; };// generic lambda, operator() is a template with one parameter
auto vglambda = [](auto printer)
{return [=](auto&&... ts) // generic lambda, ts is a parameter pack{ printer(forward<decltype(ts)>(ts)...);// nullary lambda (takes no parameters):return [=] { printer(ts...); };};
};auto p = vglambda([](auto v1, auto v2, auto v3)
{cout << v1 << " " << v2 << " " << v3 << endl;
});int main() { int x = 100;bool b = glambda(3, (x / 10) - 3.14);cout << b << endl;b = glambda(3, (x / 20) - 3.14);cout << b << endl;auto q = p(1, 'a', 3.14); // outputs 1 a 3.14q(); // outputs 1 a 3.14auto pp = vglambda(printf);pp("%s %d \n", "Sam", 45);
}
代码运行的屏幕输出
1
0
1 a 3.14
1 a 3.14
Sam 45
显式模板参数类型
如果 lambda 定义使用显式模板参数列表,则该模板参数列表将与 operator() 一起使用。对于 params 中类型指定为 auto 的每个参数,一个新的模板参数类型,将作为该模板参数列表的类型,直至到参数列表的末尾:
#include <iostream>
#include <iostream>
#include <fstream>using namespace std;struct A
{A(int&& n) { cout << "rvalue overload, n=" << n << '\n'; }A(int& n) { cout << "lvalue overload, n=" << n << '\n'; }
};class foo
{
public:template<class T1, class T2, class T3>foo(T1&& t1, T2&& t2, T3&& t3) :a1_{forward<T1>(t1)},a2_{forward<T2>(t2)},a3_{forward<T3>(t3)}{}private:A a1_, a2_, a3_;
};// generic lambda, operator() is a template with two parameters
auto glambda = []<class T>(T a, auto&& b) { return a < b; };// generic lambda, operator() is a template with one parameter pack
auto f1 = []<typename... Ts>(Ts&&... ts)
{return foo(forward<Ts>(ts)...);
};int main() { int x = 100;bool b = glambda(3, (x / 10) - 3.14);cout << b << endl;b = glambda(5.0, (x / 20) - 3.14);cout << b << endl;f1(1, 2, 4);
}
1
0
rvalue overload, n=1
rvalue overload, n=2
rvalue overload, n=4
其他
lambda 表达式上的异常规范exception适用于operator()。
为了名称查找、确定 this 指针的类型和值,以及访问非静态类成员,闭包类型的operator() 的主体可以认为是 lambda 表达式的一部分。
struct X
{int x, y;int operator()(int);void f(){// 下面的lambda表达式是成员函数 X::f[=]() -> int{return operator()(this->x + y); // X::operator()(this->x + (*this).y)// this has type X*};}
};
ClosureType::operator ret(*)(params)()
- 无捕获,非常规Lambda* using F = ret(*)(params); operator F() const noexcept;* using F = ret(*)(params);* constexpr operator F() const noexcept;
- 无捕获,常规lambda* template<template-params>operator fptr_t<template-params>() const noexcept;* template<template-params>constexpr operator fptr_t<template-params>() const noexcept;
仅当 lambda 表达式的捕获列表为空时,才会定义此用户定义的转换函数。该函数是一个闭合对象的成员函数, 而且具有public, constexpr, 非虚、非显式 和 const noexcept特征。
如果函数调用运算符是立即函数,则此函数是立即函数。
通用的无捕获 lambda 具有一个用户定义的转换函数模板,它具有与 operator() 相同的新模板参数表。
#include <iostream>using namespace std;void f1(int (*f)(int)) {int x = f(2);cout << "f=" << x << endl;
}void f2(char (*)(int)) {}
void h(int (*h)(int)) { // #1int x = h(3);cout << "h=" << x << endl;
}void h(char (*)(int)) {} // #2auto glambda = [](auto a) { return a; };int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OKint main()
{f1(glambda); // OK
// auto y = f2(glambda); // error: not convertibleh(glambda); // OK: calls #1 since #2 is not convertibleauto x = glambda(1);cout << "x: " << x << endl;auto y = fpi(&x);cout << "y: " << y << endl;
}
转换函数的返回值是一个指向具有 C++ 语言链接的函数指针,调用该函数时,与在闭包类型的默认构造实例上调用闭包类型的函数调用运算符具有相同的效果。
转换函数(模板)返回的值是一个指向具有 C++ 语言链接的函数的指针,调用该函数时,具有与以下相同的效果:
对于非泛型 lambda,在闭包类型的默认构造实例上调用闭包类型的operator()。
对于泛型 lambda,在闭包类型的默认构造实例上调用泛型 lambda 相应的operator() 特化。
转换函数(模板)返回的值为
如果operator()是静态的,则为具有C++语言链接的指向该operator()的指针,
否则,指向具有 C++ 语言链接的函数的指针,在调用该函数时,具有与以下相同的效果:
对于非泛型 lambda,在闭包类型的默认构造实例上调用闭包类型的operator()。
对于泛型 lambda,在闭包类型的默认构造实例上调用泛型 lambda 相应的operator() 特化。
如果函数调用运算符为 constexpr,则此函数为 constexpr。
#include <iostream>using namespace std;auto Fwd = [](int(*fp)(int), auto a) { return fp(a); };
auto C = [](auto a) { return a; };auto NC = [](auto a) { static int s; return a; };int main() { static_assert(Fwd(C, 3) == 3);// static_assert(Fwd(NC, 3) == 3); // error: no specialization can be constexpr because of static s
}
相关文章:
C++ Lambda表达式第一篇, 闭合(Closuretype)
C Lambda表达式第一篇, 闭合Closuretype ClosureType::operator()(params)auto 模板参数类型显式模板参数类型其他 ClosureType::operator ret(*)(params)() lambda 表达式是唯一的未命名,非联合,非聚合类类型(称为闭包类型&#…...
移动校园(3):处理全校课程数据excel文档,实现空闲教室查询与课程表查询
首先打开教学平台 然后导出为excel文档 import mathimport pandas as pd import pymssql serverName 127.0.0.1 userName sa passWord 123456 databaseuniSchool conn pymssql.connect(serverserverName,useruserName,passwordpassWord,databasedatabase) cursor conn.cur…...
【MySQL】1.初识MySQL
初识MySQL 一.MySQL 安装1.卸载已有的 MySQL2.获取官方 yum 源3.安装 MySQL4.登录 MySQL5.配置 my.cnf 二.MySQL 数据库基础1.MySQL 是什么?2.服务器,数据库和表3.mysqld 的层状结构4.SQL 语句分类 一.MySQL 安装 1.卸载已有的 MySQL //查询是否有相关…...
查看电脑显卡(NVIDIA)应该匹配什么版本的CUDA Toolkit
被串行计算逼到要吐时,决定重拾CUDa了,想想那光速般的处理感觉(夸张了)不要太爽,记下我的闯关记录。正好我的电脑配了NVIDIA独显,GTX1650,有菜可以炒呀,没有英伟达的要绕道了。回到正…...
优化:遍历List循环查找数据库导致接口过慢问题
前提: 我们在写查询的时候,有时候会遇到多表联查,一遇到多表联查大家就会直接写sql语句,不会使用较为方便的LambdaQueryWrapper去查询了。作为一个2024新进入码农世界的小白,我喜欢使用LambdaQueryWrapper,…...
NoSQL 之 Redis 配置与常用命令
一、关系型数据库与非关系型数据库 1、数据库概述 (1)关系型数据库 关系型数据库是一个结构化的数据库,创建在关系模型(二维表格模型)基础上,一般面向于记 录。 SQL 语句(标准数据查询语言&am…...
用SpringBoot打造坚固防线:轻松实现XSS攻击防御
在这篇博客中,我们将深入探讨如何使用SpringBoot有效防御XSS攻击。通过结合注解和过滤器的方式,我们可以为应用程序构建一个强大的安全屏障,确保用户数据不被恶意脚本所侵害。 目录 什么是XSS攻击?SpringBoot中的XSS防御策略使用…...
2024机器人科研/研发领域最新研究方向岗位职责与要求
具身智能工程师 从事具身智能领域的技术研究或产品开发,制定具身智能技术标准,利用大模型技术来提高机器人的智能化水平,研究端云协同的机器人系统框架,并赋能人形/复合等各类形态的机器人。具体内容包括不限于: 1、负…...
笔记:Newtonsoft.Json 序列化接口集合
在使用 Newtonsoft.Json 序列化接口集合时,一个常见的挑战是如何处理接口的具体实现,因为接口本身并不包含关于要实例化哪个具体类的信息。为了正确序列化和反序列化接口集合,你需要提供一些额外的信息或使用自定义的转换器来指导 Newtonsoft…...
【Unity设计模式】✨使用 MVC 和 MVP 编程模式
前言 最近在学习Unity游戏设计模式,看到两本比较适合入门的书,一本是unity官方的 《Level up your programming with game programming patterns》 ,另一本是 《游戏编程模式》 这两本书介绍了大部分会使用到的设计模式,因此很值得学习 本…...
CDH安装和配置流程
这份文件是一份关于CDH(Clouderas Distribution Including Apache Hadoop)安装的详细手册,主要内容包括以下几个部分: 1. **前言**: - CDH是基于Apache Hadoop的发行版,由Cloudera公司开发。 - 相比…...
SpringMVC:SpringMVC执行流程
文章目录 一、介绍二、什么是MVC 一、介绍 Spring MVC 是一种基于Java的Web框架,它采用了MVC(Model - View - Controller)设计模式,通过吧Model、View和Controller分离,将Web层进行职责解耦,把复杂的Web应…...
如何在前端网页实现live2d的动态效果
React如何在前端网页实现live2d的动态效果 业务需求: 因为公司需要做机器人相关的业务,主要是聊天形式的内容,所以需要一个虚拟的卡通形象。而且为了更直观的展示用户和机器人对话的状态,该live2d动画的嘴型需要根据播放的内容来…...
昇思25天学习打卡营第15天|linchenfengxue
Pix2Pix实现图像转换 Pix2Pix概述 Pix2Pix是基于条件生成对抗网络(cGAN, Condition Generative Adversarial Networks )实现的一种深度学习图像转换模型,该模型是由Phillip Isola等作者在2017年CVPR上提出的,可以实现语义/标签到…...
软考中级数据库系统工程师备考经验分享
前几天软考成绩出了,赶紧查询了一下发现自己顺利通过啦(上午63,下午67,开心),因此本文记录一下我的备考经验分享给大家。因为工作中项目管理类的知识没有系统学习过,本来想直接报名软考高级证书…...
Centos7删除MariaDB
在 CentOS 7 上删除 MariaDB 可以通过 yum 包管理器来完成。以下是一步一步的指导: 打开终端:首先,你需要打开你的 CentOS 7 系统的终端。 停止 MariaDB 服务(如果正在运行):在卸载 MariaDB 之前ÿ…...
【Docker系列】Docker 镜像构建中的跨设备移动问题及解决方案
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
C++友元函数和友元类的使用
1.友元介绍 在C++中,友元(friend)是一种机制,允许某个类或函数访问其他类的私有成员。通过友元,可以授予其他类或函数对该类的私有成员的访问权限。友元关系在一些特定的情况下很有用,例如在类之间共享数据或实现特定的功能。 友元可以分为两种类型:类友元和函数友元。…...
黑马苍穹外卖技术亮点 详情
1.使用工厂模式和策略模式实现布隆过滤器解决缓存穿透问题 Bitmap Bitmap是一种数据结构,它使用位图来表示数据。在处理大量数据时,Bitmap可以通过将每个数据元素映射到一个位,然后使用位运算来对数据进行操作。 通过使用Bitmap,…...
Python酷库之旅-第三方库Pandas(005)
目录 一、用法精讲 7、pandas.read_clipboard函数 7-1、语法 7-2、参数 7-3、功能 7-4、返回值 7-5、说明 7-6、用法 7-6-1、代码示例 7-6-2、结果输出 8、pandas.DataFrame.to_clipboard函数 8-1、语法 8-2、参数 8-3、功能 8-4、返回值 8-5、说明 8-6、用法…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
