首页 > 编程语言 >02 | C++lambda容易忽略的点

02 | C++lambda容易忽略的点

时间:2023-04-26 10:22:49浏览次数:40  
标签:02 std 20 auto C++ vector lambda

1.模板化的lambda

  1. 如果我们的 lambda 接收容器(假定我们老老实实的传入容器),并且要提取出容器中的元素类型,应该怎么做呢?
  • 之前我们可能这样做
auto f=[](auto vector){
    using T=typename decltype(vector)::value_type;
    ///......
}

首先说这样做并不明显我们要传入的参数是一个 vector 的容器,其次在实现上我们假定 vector 的内部有 value_type 这也是不合理的。

  • 现在我们可以这样(C++20标准)
auto f = []<typename T>(std::vector<T> vector){
    //....
}

这样就让 lambda 表达式有了类似函数模板的强大推导能力。

  1. 如何保证让 lambda 接收的参数就是一个 vector 容器呢?
  • 之前我们可能这样做
template <typename T>struct is_std_vector : std::false_type{};

template <typename T>struct is_std_vector<std::vector<T>> : std::true_type{};

auto f=[](auto vector){
    static_assert(is_std_vector<decltype(vector)>::value,"");
}
  • 现在 C++20 的标准也让我们省去了写 is_xxx 这种形式的类模板

2.可赋值的无状态 lambda 表达式

在C++20之前,无状态的 lambda 表达式既不能构造也无法赋值,当我们使用 std::sortstd::find_if 这类的函数时, lambda 是以函数的对象的身份通过函数参数传递进去的。可是像 map 的构造函数需要 lambda 的模板参数,相当于以函数类型的身份传递进去,奈何 map 类明明知道了该 lambda 表达式的类型却无法创建一个实例,因此我们可能写出这样的错误代码

auto greater=[](auto x,auto y){return x>y;}
std::map<std::string,int,decltype(greater)> mymap;

auto greater=[](auto x,auto y){return x>y;}

std::map<std::string,int,decltype(greater)> mymap1,mymap2;
mymap1=mymap2;

但如果我们使用了C++20标准的编译器则不会报错,甚至比函数重载还要简单。

class Person{
public:
    string name;
    int age;

    Person(string n, int a){
        name = n;
        age = a;
    }
    // bool operator<(const Person &p) const //注意这里的两个const
    // {
    //     return (age < p.age) || (age == p.age && name.length() < p.name.length()) ;
    // }
};
bool MyCompare(const Person &p1, const Person &p2) {//普通的函数
    return (p1.age < p2.age) || (p1.age == p2.age && p1.name.length() < p2.name.length());
}
auto MyCom=[](const Person &p1, const Person &p2) {//普通的函数
    return (p1.age < p2.age) || (p1.age == p2.age && p1.name.length() < p2.name.length());
};
int main(){
    // map<Person,int,decltype(&MyCompare)> group(MyCompare);
    map<Person,int,decltype(MyCom)> group;
    
    group[Person("Mark", 17)] = 40561;
    group[Person("Andrew",18)] = 40562;
    for (auto ii = group.begin() ; ii != group.end() ; ii++)
        cout << ii->first.name 
        << " " << ii->first.age
        << " : " << ii->second
        << endl;
}

3.[=,this] 形式的lambda也不算错误

在 C++20,之前我们写 [=] 就默认包含了 this 指针.但是为了和 [=,*this] 以示区分,引入了 [=,this]

形式 捕获区分
[=]或者 [=,this] 捕获了 this 指针,不过如果使用 后一种写法要用 C++20 标准
[=,*this] 捕获了对象的副本

  • 其他一些 lambda 表达式注意点
  1. 全局变量和static变量,不用也不需要捕获,直接使用即可
  2. C++14后我们可以使用 初始化捕获 ,即捕获一个表达式,并赋值给一个新变量。
int main(){
  int x=5;
  auto foo=[r=x+1](){return r;};   
}

主要的应用场景有两个:一个是捕获移动后的对象来节省内存,一个是 [tmp=*this] 来确保 this 对象析构了,也可以得到正确的结果。

参考:《现代 C++ 语言核心特性解析》

标签:02,std,20,auto,C++,vector,lambda
From: https://www.cnblogs.com/mmxingye/p/17354851.html

相关文章

  • 老杜2023最新Vue实战精讲(三)Vue组件化
    动力节点老杜全新版Vue教程笔记分享给大家学习の地止:https://www.bilibili.com/video/BV17h41137i4视频教程从Vue2开始讲解,一步一个案例,知识点由浅入深,然后很自然的过度到Vue3版本。Vue3是目前企业中使用最多的一个版本。视频中会把每一个Vue的知识点讲解的非常通透,不但举例......
  • .NET周报 【4月第4期 2023-04-23】
    国内文章2023成都.NET线下技术沙龙圆满结束https://www.cnblogs.com/edisonchou/p/2023_chengdu_dotnet_club_activity_review.html2023年4月15日周六,由MASA技术团队和成都.NET俱乐部共同主办的2023年成都.NET线下技术沙龙活动在成都市世纪城新会展中心知域空间举行,共计报名人......
  • 2023华为软挑决赛代码分享
    赛题主页决赛代码生产策略大致策略是生产456尽量平衡,如果场上4的数量(包括机器人身上的和正在生产但未生产完毕的)最少,那么优先生产4。但会有其他因素影响其优先级,包括路径上是否有其他机器人,这个工作台是否被对方工作台占领,这个工作台剩余配件数等......寻路寻路主体是A*算法,......
  • C++学习 第十二天
    今日学习内容:继承 多态 虚函数和抽象函数 继承:优点:可以实现代码复用,节省代码量分类:单继承 多继承 单继承:语法:class 子类类名:继承访问修饰符 父类类名{成员};父类:子类: 继承:继承修饰符:publicprotectedprivate当继承修饰是 public时 访问权......
  • C++ 学习 第十一天
    今日学习内容:面向对象 面向对象:优势:可以实现数据类型扩展易于理解 呈现形式:类 特性:封装:先将成员绑定为一个整体,再将被绑定成员划分权限,所以在类中,成员和成员直接不遵从代码顺序结构权限:public 公有的:类内可以访问 子类可以访问 类外可以访问privat......
  • 左值、左值表达式、左值引用 C++
     本文topics什么是左值和右值什么是左值表达式、右值表达式引用的分类之前学习Java的时候只记得在赋值表达式左边的就是左值,右边的就是右值。这个说法没有错,但今天又在C++中有学习到了关于左右值得概念,在此梳理了一些这些知识点。左值和右值左值:左值是一个对象或变量,可以代表......
  • C++数据结构(树)
    树是一种递归定义的数据结构,如果树中节点的各子树从左到右是有次序的,不能互换,则称该树为有序树,否则叫无序树。关于树的节点:节点拥有的子树的个数叫做节点的度如果度为0,那么该节点叫做叶节点或终端节点,除了根节点外的分支节点称为内部节点树的度是各节点度的最大值。节点的子......
  • PMP-02-项目的特征
    项目的三个特征:第一个特征就是独特性,每个项目都是独一无二的。第二个特征就是临时性,也叫做阶段性。不管项目持续的时间多长都有明确的开始和结束时间。第三个特征是渐进明细,项目的风险是无处不在的,具备超强的不确定性,而应对不确定性最好的方法就是渐进明细。......
  • 02-计算机组成
    02-计算机组成冯诺依曼计算机的基本特点由五大部分组成运算器、控制器、存储器、输入设备、输出设备指令和数据以同等地位存于存储器,可按地址寻访指令和数据用二进制表示指令由操作码和地址码组成存储程序以运算器为中心现代计算机硬件框图运算器(ALU-algorithmunit)......
  • 产品原型19-20230425
       ......