当前位置: 首页 > article >正文

lambda技巧之—如何在有多个判断分支的情况下,还能优雅的使用auto ?

在这里插入图片描述

假设有下面这样的代码:

在一个班级里面只有一个学生 a,每天他都来上课学习。

class Student
{
public:
    void study() {};
};

class _Class
{
public:
    Student a; 
};

int main(int argc, char* argv[])
{
    _Class clazz;
    auto& student = clazz.a;
    student.study();
    
    return 0;
}

我们会在代码中使用 auto& 来让编译器自己推导返回值类型,并通过 & 符号避免产生拷贝。

有一天,班级里来了另一个学生b,但是因为某些原因a只能周一、周三、周五来上课,而b只能周二、周四来上课,所以我们的学生类变成了这样:

class Student
{
public:
    void study() {};
};

class _Class
{
public:
    Student a;
    Student b;
};

而main函数因为增加了条件判断,导致我们不能再使用auto&,必须将其变为指针,因此我们的代码变成了这样:

int main(int argc, char* argv[])
{
    _Class clazz;
    int mondy = 1;
    Student* student;           //    auto& student = clazz.a;

    if (mondy % 2 == 1) {
        student = &clazz.a;
    } else {
        student = &clazz.b;
    }
    student->study();
    
    return 0;
}

很无奈的情况下我们必须将 auto& 退化成指针,本来简单的 clazz.a 的引用也要变成 &clazz.a ,且操作符 “.” 也要变成"->“,此时不知道屏幕前的你是否也感受到了一点代码的"臭味道”。

那如何保留我们之前 auto& 的写法呢?

方法1:

使用三目运算符,如下:

auto& student = mondy % 2 == 1 ? clazz.a : clazz.b;

在简单的情况下,使用三目运算符就解决了我们的烦恼。但是稍微增加一点复杂度呢。比如又来了个学生c呢?或者我想在条件判断里面增加其他代码呢? 三目运算符就不能满足要求了。这时候就要来到方法2.

方法2:

首先我们要知道一个关于lambda的知识点,那就是可以支持立即执行。

[]() {
   //....
} ();

像上面这样,在普通lambda后面加上(),不仅定义了一个匿名lambda,还立即执行了这个lambda。这被称为:IIFE全称为Immediately Invoked Function Express-立即执行函数(表达式)。来源于 javascript,详见:

An IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined. The name IIFE is promoted by Ben Alman in his blog.

https://developer.mozilla.org/en-US/docs/Glossary/IIFE

然后我们就可以将代码改成这样:

int main(int argc, char* argv[])
{
    _Class clazz;
    int mondy = 1;

    auto& student = [&]() -> decltype(clazz.a)& { //C++ 11
        if (mondy % 2 == 1) {
            return clazz.a;
        } else {
            return clazz.b;
        }
    }();

//    auto& student = [&]() -> auto& {            //C++ 14
//        if (mondy % 2 == 1) {
//            return clazz.a;
//        } else {
//            return clazz.b;
//        }
//    }();

    student.study();
    return 0;
}

C11的写法中,decltype 可以根据捕获参数 clazz 推导出此lambda的返回值类型,而如果使用C14即以上,lambda返回值直接使用auto&就行了。

Perfect,得益于 IIFE 的好处,我们幸运的保留的 auto& student的写法,而不用再改成丑陋的指针了。

在这里插入图片描述
关注公众号 QTShared,带你探索更多 C++/QT 相关知识。


http://www.kler.cn/news/161948.html

相关文章:

  • Gee教程5.中间件
  • 微信小程序动态加载图表[echart]
  • 假设检验(三)(单侧假设检验)
  • MongoDB日期查询详解
  • 【DevOps】Jenkins:配置jenkins 流水线/多分支流水线任务构建成功通知企业微信@相关人(二)
  • [GPT-1]论文实现:Improving Language Understanding by Generative Pre-Training
  • 【CSP】202303-1_田地丈量Python实现
  • CSS3 属性: transition过渡 与 transform动画
  • 用CHAT写一篇小短文
  • okhttp3 的简单使用
  • 类和对象,this指针
  • 通过51单片机控制28byj48步进电机按角度正反转旋转
  • 数据结构练习——素数统计
  • Redisson配置
  • 【STM32】TIM定时器输入捕获
  • WordCount 源码解析 Mapper,Reducer,Driver
  • 【环境搭建】ubuntu22安装ros2
  • 麒麟KYLINOS操作系统修改GRUB字体大小
  • lodash常用方法
  • 2023.12.1 --数据仓库之 拉链表
  • ⭐Unity 搭建UDP客户端(01) 配合网络调试助手测试
  • BUUCTF-[GYCTF2020]FlaskApp flask爆破pin
  • Docker入门:容器化原理
  • Clean 架构下的现代 Android 架构指南
  • 实验3.5 路由器的单臂路由配置
  • 装配式技术助力EHS平台系统:打造全方位的安全在线监测平台!
  • 【PTA-C语言】编程练习4 - 数组Ⅱ
  • 【面试经典150 | 二叉树】翻转二叉树
  • ubuntu内移除snap
  • VUE2+THREE.JS 按照行动轨迹移动人物模型并相机视角跟随人物