C++之STL(九)

1、函数对象

什么适合推荐使用函数对象?

需要状态的函数调用:

  • 需要状态的函数调用:
    • 函数对象可以包含成员变量,可以在多次调用中保持状态。这在某些算法中非常有用。
  • 提高性能:

    • 编译器可以更好地优化函数对象,因为它们是具体的类型,而不是函数指针或 std::function,这减少了间接调用的开销。
    • 内联(inline)函数对象的调用可以减少函数调用的开销。
  • 灵活的接口:
    • 函数对象可以有多个重载或模板版本,以适应不同的调用场景。
    • 可以使用模板参数来创建更通用和高效的代码。
  • 用于标准库算法:

    • 标准模板库(STL)的算法,如 std::sort, std::find_if, std::for_each 等,通常需要一个可调用对象作为参数。使用函数对象可以方便地传递复杂的行为。

2、自定义函数对象

第二个()为参数

#include <iostream>
using namespace std;

class FunObj
{
public:
    void operator()()
    {
        std::cout << "Hello, World!" << std::endl;
    }

    void operator()(int n)
    {
        std::cout << n << std::endl;
    }
};

int main() {
    FunObj fo;
    fo();
    fo(1);

    // 也可以构造匿名对象FunObj()
    FunObj()();
    return 0;
}

// 输出
Hello, World!
1
Hello, World!

3、函数对象与容器

#include <iostream>
using namespace std;

#include <map>

int main() {
    map<int, string> mapTest;
    mapTest.insert(map<int, string>::value_type(1, "aaaa"));
    mapTest.insert(map<int, string>::value_type(3, "cccc"));
    mapTest.insert(map<int, string>::value_type(2, "bbbb"));

    for(map<int, string>::const_iterator it = mapTest.begin(); it != mapTest.end(); ++it)
    {
        cout << it->first << "  " << it->second << endl;
    }
    return 0;
}

// 输出
1  aaaa
2  bbbb
3  cccc

从代码中可以看到,是即使我们先插入3,然后再插入2,打印出来却是按照顺序,这是因为map是一个类模板,模板中的第三个参数less是一个结构体,也就是类,里面是一个函数对象,也就是调用这个函数对象来进行比较大小。

  template <typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
	    typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
    class map
    { ...}

// less定义
  template<typename _Tp>
    struct less : public binary_function<_Tp, _Tp, bool>
    {
      _GLIBCXX14_CONSTEXPR
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x < __y; }
    };

当然我们也可以用本生提供的greater<>来进行从大到小排序

#include <iostream>
using namespace std;

#include <map>

int main() {
    map<int, string, greater<int>> mapTest;
    mapTest.insert(map<int, string>::value_type(1, "aaaa"));
    mapTest.insert(map<int, string>::value_type(3, "cccc"));
    mapTest.insert(map<int, string>::value_type(2, "bbbb"));

    for(map<int, string, greater<int>>::const_iterator it = mapTest.begin(); it != mapTest.end(); ++it)
    {
        cout << it->first << "  " << it->second << endl;
    }
    return 0;
}

// 输出
3  cccc
2  bbbb
1  aaaa

当然我们也可以自己提供函数对象

#include <iostream>
using namespace std;

#include <map>

struct MyGreater
{
    bool operator()(int left, int right) const
    {
        return left > right;
    }
};
int main() {
    map<int, string, MyGreater> mapTest;
    mapTest.insert(map<int, string>::value_type(1, "aaaa"));
    mapTest.insert(map<int, string>::value_type(3, "cccc"));
    mapTest.insert(map<int, string>::value_type(2, "bbbb"));

    for(map<int, string, MyGreater>::const_iterator it = mapTest.begin(); it != mapTest.end(); ++it)
    {
        cout << it->first << "  " << it->second << endl;
    }
    return 0;
}

// 输出
3  cccc
2  bbbb
1  aaaa

4、函数对象与算法

#include <iostream>
using namespace std;

#include <map>
#include <vector>
#include <algorithm>

void PrintFun(int n)
{
    cout << n << ' ';
}

class printObj
{
public:
    void operator()(int n)
    {
        cout << n << ' ';
    }
};

void add3(int& n)
{
    n += 3;
}

// 函数对象可以记录状态
class addObj
{
public:
    addObj(int num) : num_(num)
    {

    }
    void operator()(int& n)
    {
        n += num_;
    }
private:
    int num_;
};

class greaterObj
{
public:
    greaterObj(int num) : num_(num)
    {

    }
    bool operator()(int n)
    {
        return n > num_;
    }
private:
    int num_;
};
int main() {
    int a[] = {1, 2, 3, 4, 5};
    vector<int> v(a, a + 5);

    for_each(v.begin(), v.end(), PrintFun);
    cout << endl;

    // PrintFun也可以用函数对象实现
    for_each(v.begin(), v.end(), printObj());
    cout << endl;

    for_each(v.begin(), v.end(), add3);
    for_each(v.begin(), v.end(), PrintFun);
    cout << endl;

    // add3也可以用函数对象实现
    for_each(v.begin(), v.end(), addObj(10));
    for_each(v.begin(), v.end(), PrintFun);
    cout << endl;

    // 用count_if找到比n大的个数
    cout << count_if(a, a + 5, greaterObj(3)) << endl;
    return 0;
}

// 输出
1 2 3 4 5
1 2 3 4 5
4 5 6 7 8
14 15 16 17 18
2

5、STL中内置的函数对象

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/750330.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【路由交换技术】Cisco Packet Tracer基础入门教程(四)

Hello各位&#xff0c;好久不见&#xff0c;第四期我准备讲一下Packet Tracer中DHCP的配置&#xff0c;使用方法。 本章实验我们将拓扑中的某个路由器作为DHCP服务器&#xff08;它仍然可作为路由器使用&#xff09;&#xff0c;通过命令配置DHCP服务。独立的服务器可通过图形化…

基于VUE3+VITE+SpringBoot+Nginx部署项目之跨域配置等问题

前言&#xff1a;遇到问题&#xff0c;解决问题。 第一部分&#xff1a;VUE 配置 1、vite.config.js 文件 server: {proxy: {/api: {target: env.VITE_BASE_URL,changeOrigin: true,secure: false,rewrite: path > path.replace(/^\/api/, )}}}, 2、.env 文件 VITE_BAS…

JavaScript算法之龟兔赛跑

简介:龟兔赛跑算法,又称弗洛伊德循环检测算法,是一种在链表中非常常用的算法。它基于运动学和直觉的基本定律。本文旨在向您简要介绍该算法,并帮助您了解这个看似神奇的算法。 假设高速公路上有两辆车。其中一辆的速度为 x,另一辆的速度为 2x。它们唯一能相遇的条件是它们…

UE4 Unlua的快速使用

目录 Unlua的使用前言下载Unlua插件插件安装快速入门语法汇总模块导入多行字符串官方静态方法调用蓝图方法调用重载蓝图中的方法主动调用被重载的蓝图方法输入绑定动态绑定Lua脚本委托容器使用 延迟与协程的使用C 调用Lua 静态导出自定义类型到Lua使用网络UMG资源释放自定义加载…

如何寻找强势货币和弱势货币?

外汇交易的独特之处在于&#xff0c;它融合了两种货币的价值&#xff0c;其中一种货币的价值通过另一种货币来体现。举例来说&#xff0c;USDJPY外汇反映了美元与日元之间的价值关系&#xff0c;而EURUSD则代表了欧元与美元的价值对比。 通过开仓操作&#xff0c;我们预测一种…

继续捡钱,每天几百块!

每日操作计划&#xff1a; 标普信息科技(161128)&#xff0c;溢价8.5%&#xff0c;限购100&#xff0c;一拖七&#xff0c;单户每天700*8.5%59元 印度基金LOF(164824)&#xff0c;溢价2.6%&#xff0c;限购100&#xff0c;一拖七&#xff0c;单户每天700*2.6%18元 美元债LOF(…

如何解决Oracle中PL Developer过期

如果长时间不使用PL Deveploer&#xff0c;再次打开有可能会出现以下页面&#xff1a; 上方页面说明此软件已经过期&#xff0c;有两种方法可以解决上述问题&#xff0c;第一种&#xff1a; 操作注册表&#xff1a; WinR 输入指令“regedit”打开注册表&#xff0c;出现下方页…

List常用操作比for循环更优雅的写法

private String name; //姓名 private Integer age; //年龄 private Integer departId; //所属部门id } List list new ArrayList<>(); 复制代码 简单遍历 使用lamada表达式之前&#xff0c;如果需要遍历list时&#xff0c;一般使用增强for循环&#xff0c;代码如…

利用圆上两点和圆半径求解圆心坐标

已知圆上两点P1&#xff0c;P2&#xff0c;坐标依次为 ( x 1 , y 1 ) , ( x 2 , y 2 ) (x_1,y_1),(x_2,y_2) (x1​,y1​),(x2​,y2​)&#xff0c;圆的半径为 r r r&#xff0c;求圆心的坐标。 假定P1&#xff0c;P2为任意两点&#xff0c;则两点连成线段的中点坐标是 x m i …

Python学习笔记24:进阶篇(十三)常见标准库使用之数据压缩功能模块zlib,gzip,bz2,lzma的学习使用

前言 本文是根据python官方教程中标准库模块的介绍&#xff0c;自己查询资料并整理&#xff0c;编写代码示例做出的学习笔记。 根据模块知识&#xff0c;一次讲解单个或者多个模块的内容。 教程链接&#xff1a;https://docs.python.org/zh-cn/3/tutorial/index.html 数据压缩…

活动|华院计算受邀参加2024全球人工智能技术大会(GAITC),探讨法律大模型如何赋能社会治理

6月22至23日&#xff0c;备受瞩目的2024全球人工智能技术大会&#xff08;GAITC&#xff09;在杭州市余杭区未来科技城隆重举行。本届大会以“交叉、融合、相生、共赢”为主题&#xff0c;集“会、展、赛”为一体&#xff0c;聚“产、学、研”于一堂。值得一提的是&#xff0c;…

如何在线上快速定位bug(干货)

想必有许多人都想我刚进公司一样不会快速定位线上bug吧&#xff0c;不会快速定位bug会大大降低我们的开发效率&#xff0c;随之而来的就是工作质量下降、业绩下滑。 我总结了一些我常用的线上定位技巧&#xff0c;希望能帮助到大家&#xff01; 我这里以使用阿里云日志分析作…

【电路笔记】-MOSFET放大器

MOSFET放大器 文章目录 MOSFET放大器1、概述2、电路图3、电气特性3.1 ** I D = F ( V G S ) I_D=F(V_{GS}) ID​=F(VGS​)**特性3.2 I D = F ( V D S ) I_D=F(V_{DS}) ID​=F(VDS​)特性4、MOSFET放大器5、输入和输出电压6、电压增益7、总结1、概述 在前面的文章中,我们已经…

ThreadLocal 源码浅析

前言 多线程在访问同一个共享变量时很可能会出现并发问题&#xff0c;特别是在多线程对共享变量进行写入时&#xff0c;那么除了加锁还有其他方法避免并发问题吗&#xff1f;本文将详细讲解 ThreadLocal 的使用及其源码。 一、什么是 ThreadLocal&#xff1f; ThreadLocal 是 …

多电商账户为什么要用指纹浏览器?

随着电子商务的蓬勃发展&#xff0c;越来越多的商家选择开设多店来扩大经营规模。然而多店运营也带来了一系列的挑战&#xff0c;其中之一就是账号安全。 1. 了解反检测浏览器和代理服务器 在我们开始讨论如何有效地使用反检测浏览器之前&#xff0c;我们首先需要了解这两个工…

第三十四篇——幸存者偏差:如何避免被已知信息误导?

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华 一、背景介绍 人类顶层智慧的总结&#xff0c;一定会让我们在做事的过程中产生降维打击…

测试用例设计方法-流程分析法

一、引言 在软件开发过程中&#xff0c;测试是确保软件质量的关键环节之一。而测试用例设计作为测试过程中的重要组成部分&#xff0c;其质量和完备性直接影响到测试效果和软件的最终交付质量。 测试用例设计的目标是通过设计一组有效的测试用例来检查软件系统的各种功能和行为…

正点原子rk3588烧录linux和安卓镜像

1、烧录 Linux buildroot 系统镜像 1.1 进入 Loader 模式&#xff1a; 按住开发板上的 V&#xff08;音量&#xff09;按键不松&#xff0c;给开发板 上电或复位&#xff0c;此时烧录工具会提示&#xff1a;发现一个 LOADER 设备&#xff0c;表示开发板此时已经处于 Loader 模…

华为昇腾310B1芯片DVPP模块VENC视频编码接口调用流程以及视频编码代码梳理

目录 1 接口调用流程 2 代码流程梳理 1 接口调用流程 在CANN 8.0.RC1 AscendCL应用软件开发指南 (C&C, 推理) 01.pdf 文档中有接口调用流程 2 代码流程梳理 代码在samples: CANN Samples - Gitee.com 然后我把这个代码完整的看了一遍&#xff0c;然后梳理了详细的代码…

Transformers 安装及 google-t5/t5-small 机器翻译示例

文章目录 Github文档推荐文章简介安装官方示例google-t5/t5-small使用脚本进行训练Pytorch 机器翻译数据集下载数据集格式转换 Github https://github.com/huggingface/transformers 文档 https://huggingface.co/docs/transformers/indexhttps://github.com/huggingface/tr…