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函数、可变参数模板


这两个内容没有什么联系, 只是放到一起做一下笔记.


1. lambda函数

python中有lambda函数的用法:

list(map(lambda x: x**2, [1, 2, 3, 4]))

输出:

1, 4, 9, 16

lambda函数是对于表达式不太长的较简单的功能, 尽量缩短代码提高可读性的一种手段. 实际上C++里面也有. 如果从例子入手的话, 比如说, 我要对一个类进行自定义排序. 定义如下的牛马类, 对于一个数组的牛马, 将收入从小到大排. 对于收入相同的, 将年龄从大到小排:

class CowHorse{
private:
    std::string m_name; 
    int m_age;
    double m_salary;
public:
    CowHorse(const std::string& name, const int age, const double salary) : m_name(std::move(name)), m_age(age), m_salary(salary) {}
    bool operator<(CowHorse& ch);
    friend std::ostream& operator<<(std::ostream& os, CowHorse& ch);
};

方法一. 重载<运算符
因为sort函数默认是通过从小到大排序(std::less), 所以我们重载<运算符:

bool CowHorse::operator<(CowHorse& ch){
    if (this->m_salary != ch.m_salary)
        return this->m_salary < ch.m_salary;
    else 
        return this->m_age > ch.m_age;
}

运行

void func(){
    std::vector<CowHorse> arr;
    arr.push_back(CowHorse("amy", 35, 3000));
    arr.push_back(CowHorse("bob", 85, 3000));
    arr.push_back(CowHorse("damengzi", 45, 9000));
    arr.push_back(CowHorse("fool", 25, 1000));

    sort(arr.begin(), arr.end());

    for (auto& item: arr){
        std::cout << item;
    }

}

输出结果:

fool 25 1000
bob 85 3000
amy 35 3000
damengzi 45 9000

方法二. 仿函数
仿函数, 可以理解为函数对象, 即它可以是一个struct或class, 但用的时候当作函数来用, 为此需要重载()运算符. 定义自定义排序的类如下:

struct myCmp_{
    bool operator()(CowHorse& ch0, CowHorse& ch1){
        return ch0 < ch1;
    }
};

调用sort时, 第三个参数传入实例化的myCmp_类:

sort(arr.begin(), arr.end(), myCmp_());

结果也是正确的.
方法三. 函数指针
当然, 更简洁的方式是直接定义函数(因为这个例子比较简单):

bool myCmpFunc(CowHorse& ch0, CowHorse& ch1){
    return ch0 < ch1;
}

在调用sort时传入函数指针:

sort(arr.begin(), arr.end(), myCmpFunc);

方法四. lambda函数
lambda函数的格式为:

[返回值](参数){函数体}

或者

[](参数)->返回值类型{函数体}

因此可以这样写:

sort(arr.begin(), arr.end(), [&](CowHorse& ch0, CowHorse& ch1){return ch0 < ch1; });

其中[&]的意思是按引用接收. 在这里用不用这个都可以.

2. 可变参数模板

我们知道, python中有*args与**kwargs用于定义函数的可变参数.

>>> def test(**kwargs):
...     if 'name' in kwargs:
...         print(kwargs['name'])
...
>>> test(name='asds')

因此, 我们在不确定函数输入参数的时候, 可以这样来用, 并且加条件判断即可. 这样有助于泛化性.
C++中也有这项功能, 只不过不如python这么强大(C++中的可变参数不是哈希表, 不能向上面那样索引)

例如, 我们要定义一个函数, 打印它所有的参数值:

void func() {return;}

template<typename T, typename... Args>  // Args是模板参数包, ...放前面
void func(T t, Args... args){  // 函数参数包作为函数参数
   std::cout << t;  // 打印第一项
   func(args...);  // 递归调用. 函数参数包后面跟省略号. 注意, 当args为空时, 由于func()未定义, 因此要重载一个func的版本.
}



int main(){
    std::string name = "ajsdqwq";
    func(name, name, name, name);

    system("pause");
    return 0;
}

输出:

ajsdqwqajsdqwqajsdqwqajsdqwq

其中, 模板参数包Args是一个类型的列表, 而函数参数包args是一个值的列表, 二者是一一对应的.

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-21 00:08:17  更:2022-09-21 00:11:16 
 
开发: 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/19 12:11:29-

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