C++ 学习之函数对象

news2024/12/25 13:56:12

在这里插入图片描述

C++ 函数对象基本概念

在C++中,函数对象(Function Objects)是一种类或结构体,它重载了函数调用运算符operator(),因此可以像函数一样被调用。函数对象有时也被称为仿函数(Functor)。

以下是关于C++函数对象的基本概念:

  1. 使用函数对象:函数对象可以像普通函数一样被调用,通过在对象后加括号并传递参数来执行操作。例如:

    #include <iostream>
    
    struct Add {
        int operator()(int a, int b) { return a + b; }
    };
    
    int main() {
        Add adder;
        std::cout << adder(3, 4) << std::endl;  // 调用函数对象
        return 0;
    }
    
  2. 重载operator():函数对象需要重载operator(),并根据需要定义参数和返回值。通过重载operator(),函数对象就可以像函数一样被调用。

  3. 状态保持:与普通函数不同的是,函数对象可以包含状态。这意味着函数对象可以在其内部保持一些状态信息,并在每次调用时进行更新。这使得函数对象更加灵活且功能强大。

  4. 模板函数对象:函数对象可以是模板类,可以接受不同类型的参数。这样可以实现更通用和灵活的函数对象,适用于多种情况。

  5. 标准库中的函数对象:C++标准库提供了许多预定义的函数对象,如std::plusstd::minusstd::greater等,可以直接使用这些函数对象完成特定的操作,而不用自己定义函数对象。

  6. 使用场景:函数对象通常用于泛型编程、STL算法、排序、自定义比较函数等情况。通过函数对象,我们可以定义自己的函数行为,并将其应用于各种数据结构和算法中。

通过函数对象,C++提供了一种更加灵活和可定制的函数调用方式,使编程变得更加方便和高效。

C++ 函数对象使用

在C++中,函数对象(Function Objects)可以通过类或结构体重载operator()来实现,从而使其像函数一样被调用。使用函数对象可以提供更灵活和通用的函数行为,适用于各种情况。以下是一些关于如何定义和使用函数对象的示例:
在这里插入图片描述

示例1:定义一个简单的函数对象并调用

#include <iostream>

// 定义一个加法函数对象
struct Add {
    int operator()(int a, int b) {
        return a + b;
    }
};

int main() {
    Add adder; // 创建函数对象
    int result = adder(3, 4); // 调用函数对象
    std::cout << "Result: " << result << std::endl;
    return 0;
}

示例2:利用函数对象实现自定义排序

#include <iostream>
#include <vector>
#include <algorithm>

// 自定义升序排序函数对象
struct AscendingOrder {
    bool operator()(int a, int b) {
        return a < b;
    }
};

int main() {
    std::vector<int> numbers = {5, 2, 8, 1, 4};
    
    // 使用函数对象进行升序排序
    AscendingOrder ascending_order;
    std::sort(numbers.begin(), numbers.end(), ascending_order);
    
    // 输出排序结果
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    
    return 0;
}

示例3:利用标准库提供的函数对象

#include <iostream>
#include <algorithm>
#include <vector>

int main() {
    std::vector<int> numbers = {5, 2, 8, 1, 4};
    
    // 使用标准库提供的函数对象std::greater进行降序排序
    std::sort(numbers.begin(), numbers.end(), std::greater<int>());
    
    // 输出排序结果
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    
    return 0;
}

通过这些示例,您可以看到如何定义和使用函数对象来实现自定义操作、排序、比较等功能。函数对象在STL算法、泛型编程、模板编程等方面有着广泛的应用,能够使代码更通用、可复用和高效。

C++ 一元谓词

在这里插入图片描述

在C++中,一元谓词(Unary Predicate)是一个函数对象或函数指针,它接受一个参数并返回一个bool值。一元谓词通常用于标准库算法中,作为条件判断或过滤的依据。一元谓词的主要特点是只接受一个参数。

下面是一个简单的示例来说明一元谓词的用法:

#include <iostream>
#include <vector>
#include <algorithm>

// 一元谓词函数对象,用于判断一个整数是否为偶数
struct IsEven {
    bool operator()(int n) {
        return n % 2 == 0;
    }
};

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    
    // 使用一元谓词IsEven进行筛选,只保留偶数
    auto it = std::remove_if(numbers.begin(), numbers.end(), IsEven());

    // 调用erase方法擦除不符合条件的元素
    numbers.erase(it, numbers.end());

    // 输出结果
    for(int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

在这个示例中,我们定义了一个一元谓词函数对象IsEven,它判断一个整数是否为偶数。然后我们使用std::remove_if算法结合该一元谓词对容器numbers进行筛选,去除所有不满足条件的元素,最后输出剩余的偶数。

一元谓词在很多情况下都非常有用,可以帮助我们根据自定义的条件来进行数据筛选、操作等。通过使用一元谓词,您可以更灵活地控制算法的行为,并适应各种需求。

C++ 二元谓词

在C++中,二元谓词(Binary Predicate)是一个函数对象或函数指针,它接受两个参数并返回一个bool值。二元谓词通常在标准库算法中使用,用于比较两个元素或判断它们之间的关系。

下面是一个简单的示例来说明二元谓词的用法:

#include <iostream>
#include <vector>
#include <algorithm>

// 二元谓词函数对象,用于比较两个整数的大小关系
struct Compare {
    bool operator()(int a, int b) {
        return a < b;
    }
};

int main() {
    std::vector<int> numbers = {4, 2, 7, 3, 9, 5};

    // 使用二元谓词Compare进行排序
    std::sort(numbers.begin(), numbers.end(), Compare());

    // 输出排序结果
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

在这个示例中,我们定义了一个二元谓词函数对象Compare,它比较两个整数的大小关系。然后我们使用std::sort算法结合该二元谓词对容器numbers进行排序,按照自定义的比较函数对象来重新排列元素顺序。

二元谓词在排序、查找、删除等需要考虑元素之间关系的情况下非常有用。通过提供自定义的二元谓词,我们可以灵活地控制算法的行为,满足各种不同的需求。

C++ 函数对象算数仿函数

函数对象(Function Objects)在C++中也可以作为算术仿函数(Arithmetic Functors)使用,它们模拟了基本的算术操作符(如加法、减法、乘法和除法),使其能够像函数一样被调用。

以下是一些示例说明如何使用函数对象作为算术仿函数:

示例1:使用函数对象实现加法仿函数

#include <iostream>

// 定义一个加法仿函数
struct Add {
    int operator()(int a, int b) const {
        return a + b;
    }
};

int main() {
    Add adder; // 创建加法仿函数对象
    int result = adder(3, 4); // 调用加法仿函数
    std::cout << "Result: " << result << std::endl;
    return 0;
}

示例2:使用函数对象实现乘法仿函数

#include <iostream>

// 定义一个乘法仿函数
struct Multiply {
    int operator()(int a, int b) const {
        return a * b;
    }
};

int main() {
    Multiply multiplier; // 创建乘法仿函数对象
    int result = multiplier(3, 4); // 调用乘法仿函数
    std::cout << "Result: " << result << std::endl;
    return 0;
}

示例3:使用标准库提供的算术仿函数

#include <iostream>
#include <functional>

int main() {
    std::plus<int> adder; // 创建加法仿函数对象
    int result = adder(3, 4); // 调用加法仿函数
    std::cout << "Result: " << result << std::endl;

    std::multiplies<int> multiplier; // 创建乘法仿函数对象
    result = multiplier(3, 4); // 调用乘法仿函数
    std::cout << "Result: " << result << std::endl;

    return 0;
}

通过这些示例,您可以看到如何使用函数对象作为算术仿函数,从而进行加法和乘法运算。您可以自定义函数对象来实现更复杂的算术操作,或者使用标准库提供的算术仿函数(如std::plusstd::multiplies)来简化代码。

C++ 函数对象关系仿函数

函数对象关系仿函数(Function Object Relational Functors)用于比较两个对象之间的关系,例如相等、不相等、大于、小于等。它们通常被用于需要排序、查找或筛选操作中。

以下是一些示例说明如何使用函数对象关系仿函数:

示例1:使用函数对象关系仿函数进行相等判断

#include <iostream>
#include <functional>

int main() {
    std::equal_to<int> isEqual; // 创建相等仿函数对象
    bool result = isEqual(3, 4); // 判断两个数是否相等
    std::cout << "Is equal: " << std::boolalpha << result << std::endl;
    return 0;
}

示例2:使用函数对象关系仿函数进行大小比较

#include <iostream>
#include <functional>

int main() {
    std::greater<int> isGreater; // 创建大于仿函数对象
    bool result = isGreater(3, 4); // 判断第一个数是否大于第二个数
    std::cout << "Is greater: " << std::boolalpha << result << std::endl;

    std::less<int> isLess; // 创建小于仿函数对象
    result = isLess(3, 4); // 判断第一个数是否小于第二个数
    std::cout << "Is less: " << std::boolalpha << result << std::endl;

    return 0;
}

示例3:自定义函数对象关系仿函数进行字符串长度比较

#include <iostream>
#include <string>

// 自定义字符串长度比较仿函数
struct StringLengthComparator {
    bool operator()(const std::string& str1, const std::string& str2) const {
        return str1.length() < str2.length();
    }
};

int main() {
    StringLengthComparator compareLength; // 创建字符串长度比较仿函数对象
    bool result = compareLength("apple", "banana"); // 判断第一个字符串的长度是否小于第二个字符串的长度
    std::cout << "Is length less: " << std::boolalpha << result << std::endl;
    return 0;
}

通过这些示例,您可以看到如何使用函数对象关系仿函数来进行对象之间的关系判断。您可以使用标准库提供的函数对象关系仿函数(如std::equal_tostd::greaterstd::less),也可以自定义函数对象关系仿函数来满足特定需求。

C++ 函数对象逻辑仿函数

函数对象逻辑仿函数(Function Object Logical Functors)用于执行逻辑运算,比如逻辑与、逻辑或、逻辑非等操作。它们通常被用于需要对多个条件进行组合判断的情况。

以下是一些示例说明如何使用函数对象逻辑仿函数:

示例1:使用函数对象逻辑仿函数进行逻辑与操作

#include <iostream>
#include <functional>

int main() {
    std::logical_and<bool> andOp; // 创建逻辑与仿函数对象
    bool result = andOp(true, false); // 判断两个条件是否同时为真
    std::cout << "Logical AND result: " << std::boolalpha << result << std::endl;
    return 0;
}

示例2:使用函数对象逻辑仿函数进行逻辑或操作

#include <iostream>
#include <functional>

int main() {
    std::logical_or<bool> orOp; // 创建逻辑或仿函数对象
    bool result = orOp(true, false); // 判断两个条件是否至少有一个为真
    std::cout << "Logical OR result: " << std::boolalpha << result << std::endl;
    return 0;
}

示例3:自定义函数对象逻辑仿函数进行逻辑非操作

#include <iostream>

// 自定义逻辑非仿函数
struct LogicalNot {
    bool operator()(bool value) const {
        return !value;
    }
};

int main() {
    LogicalNot notOp; // 创建逻辑非仿函数对象
    bool result = notOp(true); // 对给定条件取逻辑非
    std::cout << "Logical NOT result: " << std::boolalpha << result << std::endl;
    return 0;
}

通过这些示例,您可以看到如何使用函数对象逻辑仿函数来执行逻辑运算。您可以使用标准库提供的逻辑仿函数(如std::logical_andstd::logical_or),也可以自定义函数对象逻辑仿函数来实现特定的逻辑操作。

关注我,不迷路,共学习,同进步

在这里插入图片描述

关注我,不迷路,共学习,同进步

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

备战蓝桥杯---基础算法刷题2

题目有一点水&#xff0c;不过还是有几个好题的&#xff0c;我在这分享一下&#xff1a; 很容易想到先往最高处跳再往最低处跳&#xff0c;依次类推&#xff0c;那怎么保证其正确性呢&#xff1f; 证法1. 在此&#xff0c;我们从0开始&#xff0c;假设可以跳到a,b,c(a<b<…

Linux中消息队列

消息队列 概念 消息队列是System V IPC对象的一种消息队列有消息队列ID来唯一标识消息队列就是一个消息列表。用户可以在消息队列中添加消息、读取信息等消息队列可以按照类型来发送/结束消息 消息队列使用步骤 打开/创建消息队列 msgget向消息队列发送信息 msgsnd从消息队…

4.4 MySQL存储

目录 1、使用前提 2、使用连接数据库最初步骤 2.1 最初步骤 2.2 connect()方法中参数简单传递 3、创建数据库(创建架构)和创建表 3.1 创建数据库(创建架构) 3.2 创建表 3.2.1 基本创建 3.2.2 创建自增主键 4、Pycharm 可视化连接 MySQL 图形界面 5、插入、更新、查询…

项目管理工具git

git 1. git介绍1.1. 版本控制系统 2. 创建本地版本库2.1 概念2.2 操作步骤 3. 修改文件4. 练习: 添加一个本地项目到仓库5. 添加远程仓库5.1 添加远程仓库5.2 本地仓库同步到远程仓库5.3 克隆远程仓库到本地5.4 SSH设置 6. 分支管理6.1 创建分支6.2 切换分支6.3 合并分支6.4 解…

基于yolov5的苹果检测(pytorch框架)【python源码+UI界面+功能源码详解】

功能演示&#xff1a; 基于yolov5的苹果检测系统&#xff0c;系统既能够实现图像检测&#xff0c;也可以进行视屏和摄像实时检测_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于yolov5的苹果检测系统是在pytorch框架下实现的&#xff0c;这是一个完整的项目&#xf…

Go语言必知必会100问题-06 生产者端接口

生产者端接口 Go语言必知必会100问题-05 接口污染中介绍了程序中使用接口是有价值的。在编码的时候&#xff0c;接口应该放在哪里呢&#xff1f;这是Go开发人员经常有误解的一个问题&#xff0c;本文将深入分析该问题。 在深入探讨问题之前&#xff0c;先对提及的术语做一个定…

如何使用Inno Setup制作Unity构建程序的Windows安装程序

1. 准备 &#xff08;1&#xff09;准备好Unity构建的程序集合 必须包括&#xff1a; Data文件夹&#xff08;xxx_Data&#xff09; Mono文件夹&#xff08;MonoBleedingEdge&#xff09; 打包的应用程序文件&#xff08;xxx.exe&#xff09; Unity播放器dll文件&#xff…

mac flutter 配置

下载Flutter Sdk 直接访问官网无法下载&#xff0c;需要访问中国镜像下载 Flutter SDK 归档列表 - Flutter 中文文档 - Flutter 中文开发者网站 - Flutter Start building Flutter Android apps on macOS - Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 下载后解压…

HCIA-Datacom实验指导手册:5.1 实验一:FTP SFTP TFTP 基础配置实验

HCIA-Datacom实验指导手册&#xff1a;5.1 实验一&#xff1a;FTP 基础配置实验 一、实验介绍&#xff1a;二、实验拓扑&#xff1a;三、实验目的&#xff1a;四、配置步骤&#xff1a;步骤 1 设备基础配置步骤 2 在 Router 上配置 FTP 和SFTP服务器功能及参数步骤 3 配置本地 …

大厂经验谈之OKR目标管理

前言 这是大厂经验谈系列第一篇文章,来看看互联网公司是如何制定和管理目标的。OKR是目前互联网公司经常采用的目标管理工具,最开始也是由国外著名公司推崇,比如Google、微软、亚马逊等,后面才逐步引入国内。既然是工具就有用得好和不好的地方,很多团队仍然把OKR当做KPI来…

【人工智能高频面试题--基本篇】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;人工智能高频面试题 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 人工智能高频面试题--基本篇 1.深度学习和过往的神经网络训练方法有什么区别&#xff1f;列举…

2024年 前端JavaScript入门到精通 第四天 笔记

4.1 函数的基本使用以及封装练习 ★ 函数命名规范 4.2 函数的参数以及默认参数 函数的灵魂&#xff01;&#xff01;&#xff01; 4.3 函数封装数组求和案例 4.4 函数返回值return 4.5 函数返回值细节以及上午总结 4.6 函数返回值案例-求最大值和最 4.7 函数复习以及断点进入函…

php脚本输出中文在浏览器中显示乱码

问题说明 这个问题一般出现在较低版本的php中&#xff0c;原因是php和浏览器的字符解析方式不对应 &#xff0c;导致中文字符被错误解析成乱码 &#xff08;注&#xff0c;此处的php版本任意切换是依赖于小皮面板&#xff08;phpstudy&#xff09;实现的&#xff0c;感兴趣可以…

132 Linux 系统编程9 ,IO操作,lseek 函数,truncate函数,查看文件的表示形式

一 lseek 函数 函数说明&#xff1a;此函数用于文件偏移 Linux中可使用系统函数lseek来修改文件偏移量(读写位置) 每个打开的文件都记录着当前读写位置&#xff0c;打开文件时读写位置是0&#xff0c;表示文件开头&#xff0c;通常读写多少个字节就会将读写位置往后移多少个字…

2024国际生物发酵展览会全面揭秘-西尼尔过程控制

参展企业检查 西尼尔&#xff08;南京&#xff09;过程控制有限公司成立于2007年&#xff0c;坐落于美丽的六朝古都南京&#xff0c;占地面积20000平方米&#xff0c;现有员工130人&#xff0c;其中70%为本科及以上学历&#xff0c;高级、中级专业技术人员占比30%以上。 公司为…

[NOIP2011 普及组] 数字反转

AC代码&#xff1a; #include<iostream>using namespace std;int main() {long long n;cin >> n;long long temp n;long long sum 0;while(temp ! 0){int c temp % 10;sum sum * 10 c;temp temp / 10;}printf("%lld",sum);return 0; }

BUUCTF第二十四、二十五题解题思路

目录 第二十四题CrackRTF 第二十五题[2019红帽杯]easyRE1 第二十四题CrackRTF 查壳 无壳&#xff0c;32位&#xff0c;用32位IDA打开&#xff0c;打开后的main函数很短&#xff0c;可以找到一句“jmz _main_0”——跳转到 _main_0&#xff0c;说明真正的主函数是_main_0&am…

Rem 自适应原理与应用

前言 移动端适配有很多方案&#xff0c;这篇文章将根据 rem 自适应的原理进行讲解&#xff0c;接下来跟着作者的思路一起来看看吧&#xff01; 原理 在搞清楚 rem 适配之前&#xff0c;我们先来了解一下什么是 rem&#xff1f; rem 是一种相对长度单位&#xff0c;它相对于根…

Mysql学习之事务日志undolog深入剖析

Undo log redo log 是事务持久性的保证&#xff0c;undo log是事务原子性的保证。在事务中更新数据的前置操作其实是要先写入一个undo log。 如何理解undo 日志&#xff1f; 事务需要保证原子性&#xff0c;也就是事务中的操作要么全部完成&#xff0c;要么什么也不做。但有时…

SQLServer 格式化数据的方法

格式化数据一般考虑使用FORMAT 或者CONVERT ​​​​​​​函数&#xff0c;FORMAT 函数是在 SQL Server 2012 中引入的&#xff0c;如果你使用的是较早版本的 SQL Server&#xff0c;则可能需要考虑使用其他方法&#xff0c;如 CONVERT 函数。 在 SQL Server 中&#xff0c;FO…