C++常见的仿函数,预定义函数,functor,二元操作函数(对vector操作,加减乘除取余位运算等 )

C++ 标准库在 <functional> 头文件中为我们提供了一套非常方便的预定义函数对象(也称为“仿函数”或 “functor”),它们可以像变量一样直接传递给 std::reduce 和其他标准算法。

你提到的 std::bit_orstd::multiplies 就是其中的成员。这些函数对象的好处是代码更具可读性,并且可以避免手写简单的 lambda 表达式。

从 C++14 开始,这些函数对象大多有了“透明”版本(使用 std::plus<> 而不是 std::plus<int>),这让它们使用起来更加方便,因为你不需要手动指定类型,编译器会自动推断。

下面是这些常用函数对象的分类介绍和 std::reduce 的使用示例。


1. 算术操作 (Arithmetic Functors)

这些是最常见的聚合操作。

函数对象 (透明版本)作用C++ 操作符示例 reduce 初始值
std::plus<>()加法a + b00.0
std::minus<>()减法a - bN/A (不满足结合律)
std::multiplies<>()乘法a * b11.0
std::divides<>()除法a / bN/A (不满足结合律)
std::modulus<>()取模a % bN/A (不满足结合律)
std::negate<>()取反 (一元)-a(不适用于reduce)

注意: minusdivides 通常不用于 std::reduce,因为它们不满足并行计算所必需的结合律(((a-b)-c)-d) 的结果与 (a-b) + (c-d) 通常是不同的。

代码示例:

#include <iostream>
#include <vector>
#include <numeric>
#include <functional> // 必须包含int main() {std::vector<int> nums = {1, 2, 3, 4, 5};// 求和int sum = std::reduce(nums.begin(), nums.end(), 0, std::plus<>());std::cout << "Sum: " << sum << std::endl; // 输出: 15// 求积long long product = std::reduce(nums.begin(), nums.end(), 1LL, std::multiplies<>());std::cout << "Product: " << product << std::endl; // 输出: 120
}

2. 位运算 (Bitwise Functors)

这些在你需要对一系列整数进行位操作时非常有用。

函数对象 (透明版本)作用C++ 操作符示例 reduce 初始值
std::bit_and<>()按位与a & b~0 (所有位都为1)
std::bit_or<>()按位或`ab`
std::bit_xor<>()按位异或a ^ b0
std::bit_not<>()按位取反 (一元)~a(不适用于reduce)

代码示例:

#include <iostream>
#include <vector>
#include <numeric>
#include <functional>int main() {std::vector<unsigned int> flags = {0b0001, 0b0010, 0b1000}; // 1, 2, 8// 将所有标志位合并 (OR)// 0 | 1 | 2 | 8 = 11 (0b1011)unsigned int all_flags = std::reduce(flags.begin(), flags.end(), 0u, std::bit_or<>());std::cout << "All flags (OR): " << all_flags << std::endl; // 输出: 11// 找到所有共有位 (AND)std::vector<unsigned int> masks = {0b1101, 0b0111, 0b1111};// 0b1101 & 0b0111 & 0b1111 = 0b0101 (5)// 初始值需要是全1,否则任何数与0做&运算都会得到0unsigned int common_bits = std::reduce(masks.begin(), masks.end(), ~0u, std::bit_and<>());std::cout << "Common bits (AND): " << common_bits << std::endl; // 输出: 5
}

3. 逻辑运算 (Logical Functors)

这些通常用于聚合布尔值。

函数对象 (透明版本)作用C++ 操作符示例 reduce 初始值
std::logical_and<>()逻辑与a && btrue
std::logical_or<>()逻辑或`a
std::logical_not<>()逻辑非 (一元)!a(不适用于reduce)

代码示例:

#include <iostream>
#include <vector>
#include <numeric>
#include <functional>int main() {std::vector<bool> conditions = {true, false, true};// 检查是否所有条件都为真 (AND)bool all_true = std::reduce(conditions.begin(), conditions.end(), true, std::logical_and<>());std::cout << "All true? " << std::boolalpha << all_true << std::endl; // 输出: false// 检查是否至少一个条件为真 (OR)bool any_true = std::reduce(conditions.begin(), conditions.end(), false, std::logical_or<>());std::cout << "Any true? " << std::boolalpha << any_true << std::endl; // 输出: true
}

4. 比较运算 (Comparison Functors) - 用于求最值

比较运算符本身不直接用于聚合,但它们是构建求最大/最小值逻辑的核心。虽然你可以直接使用 lambda 表达式 std::minstd::max,但了解它们的存在也很有用。

函数对象 (透明版本)作用C++ 操作符
std::equal_to<>()等于a == b
std::not_equal_to<>()不等于a != b
std::greater<>()大于a > b
std::less<>()小于a < b
std::greater_equal<>()大于等于a >= b
std::less_equal<>()小于等于a <= b

求最值的最佳实践是使用 Lambda 表达式,因为它们更清晰。

代码示例:

#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm> // for std::min/maxint main() {std::vector<int> nums = {10, -5, 100, 30, -20};if (nums.empty()) return 1;// 求最大值// 初始值设为第一个元素,避免空容器或所有元素都为负数的问题int max_val = std::reduce(std::next(nums.begin()), // 从第二个元素开始nums.end(),              // 到末尾nums.front(),            // 初始值为第一个元素[](int a, int b) { return std::max(a, b); } // 使用 std::max);std::cout << "Max value: " << max_val << std::endl; // 输出: 100// 求最小值int min_val = std::reduce(std::next(nums.begin()),nums.end(),nums.front(),[](int a, int b) { return std::min(a, b); } // 使用 std::min);std::cout << "Min value: " << min_val << std::endl; // 输出: -20
}

总结

  • <functional> 头文件是你的好朋友,它提供了丰富的预定义函数对象。
  • 使用透明函数对象(如 std::plus<>())是现代C++的最佳实践,代码更简洁。
  • 对于简单的、标准的操作(加、乘、位运算),直接使用这些函数对象非常方便。
  • 对于更复杂的逻辑,尤其是求最值,Lambda 表达式通常是更灵活、更具可读性的选择。
  • 使用 reduce 时,选择正确的初始值至关重要,它决定了整个计算的基础。

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

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

相关文章

【RH134 问答题】第 6 章 管理 SELinux 安全性

目录SELinux 是如何保护资源的&#xff1f;什么是自由决定的访问控制(DAC)&#xff1f;它有什么特点&#xff1f;什么是强制访问控制(MAC)&#xff1f;它有什么特点&#xff1f;什么是 SELinux 上下文&#xff1f;setenforce 0 命令的作用是什么&#xff1f;定义一条 SELinux 文…

【MacOS】发展历程

很高兴为您详细介绍 macOS 的详细发展历程。macOS 是苹果公司开发的操作系统&#xff0c;用于 Mac 电脑、iPad 和 Apple TV 等设备。以下是 macos 的主要版本和发展历程&#xff1a;1. System 7 (1991)发布日期&#xff1a;1991年特点&#xff1a;引入多任务处理功能。改进了拖…

智慧社区项目开发(二)——基于 JWT 的登录验证功能实现详解

在 Web 应用中&#xff0c;登录验证是保障系统安全的核心环节。本文将结合具体接口文档&#xff0c;详细讲解如何基于 JWT&#xff08;JSON Web Token&#xff09;实现登录验证功能&#xff0c;包括 JWT 配置、工具类封装、登录流程处理等关键步骤&#xff0c;帮助开发者快速理…

Jmeter的元件使用介绍:(七)后置处理器详解

Jmeter的后置处理器主要用于取样器执行后的提取数据操作。 Jmeter常用的后置处理器有:Json提取器、正则表达式提取器、边界提取器、Beanshell后置处理器。此外还有Xpath提取器、CSS选择器提取器等&#xff0c;由于这两项多用前端页面提取元素&#xff0c;目前的项目基本都是采…

Allure的安装,在Pytest中的简单使用以及生成测试报告

目录 1.Allure的安装 1--下载网址 2--选择对应系统版本下载 3--配置Allure环境变量 4--验证安装是否成功 5--配置JAVAJDK的环境变量&#xff08;如果已经配置&#xff0c;可以忽视这一步&#xff09; 2.python中pytestAllure 1--python安装Allure包 2--生成测试报告 1--使用pyt…

Oracle 数据库报 ora-00257 错误并且执行alter system switch logfile 命令卡死的解决过程

Oracle 数据库报 ora-00257 错误并且执行alter system switch logfile 命令卡死的解决过程 7月26日下午&#xff0c;某医院用户的 HIS 系统无法连接&#xff0c;报如下错误&#xff1a;初步判断是归档日志问题。 用户的 HIS 系统数据库是双节点 Oracle 11g Rac 集群。登录服务器…

ArKTS:List 数组

一种&#xff1a;/**# encoding: utf-8# 版权所有 2025 ©涂聚文有限公司™ # 许可信息查看&#xff1a;言語成了邀功盡責的功臣&#xff0c;還需要行爲每日來值班嗎# 描述&#xff1a; 数组# Author : geovindu,Geovin Du 涂聚文.# IDE : DevEco Studio 5.1.1 …

Spring Boot 3整合Spring AI实战:9轮面试对话解析AI应用开发

Spring Boot 3整合Spring AI实战&#xff1a;9轮面试对话解析AI应用开发 第1轮&#xff1a;基础配置与模型调用 周先生&#xff1a;cc&#xff0c;先聊聊Spring AI的基础配置吧。如何在Spring Boot 3项目中集成Ollama&#xff1f; cc&#xff1a;我们可以通过OllamaConfig.java…

标准SQL语句示例

一、基础操作1. 数据库操作-- 1. 创建数据库 CREATE DATABASE 数据库名称 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;-- 2. 删除数据库 DROP DATABASE IF EXISTS 数据库名称;-- 3. 选择数据库 USE 数据库名称;-- 4. 显示所有数据库 SHOW DATABASES;-- 5. 查看数据库创…

STM32-基本定时器

一.基本定时器简介 STM32F1 系列共有 8 个定时器&#xff0c;分别为&#xff1a;基本定时器、通用定时器、高级定时器。基本定时器 TIM6 和 TIM7 是一个 16 位的只能向上计数的定时器&#xff0c;只能定时&#xff0c;没有外部IO。 二.基本定时器功能 上图为基本定时器的功能框…

ofd文件转pdf

主要后端使用Java实现&#xff0c;前端可随意搭配http请求添加依赖&#xff1a;<!-- OFD解析与转换库 --><dependency><groupId>org.ofdrw</groupId><artifactId>ofdrw-converter</artifactId><version>1.17.9</version></…

4.应用层自定义协议与序列化

1.应用层程序员写的一个个解决我们实际问题, 满足我们日常需求的网络程序, 都是在应用层1.1再谈“协议”协议是一种 "约定". socket api 的接口, 在读写数据时, 都是按 "字符串" 的方式来发送接收的. 如果我们要传输一些 "结构化的数据" 怎么办呢…

【QT搭建opencv环境】

本文参考以下文章&#xff1a; https://blog.csdn.net/weixin_43763292/article/details/112975207 https://blog.csdn.net/qq_44743171/article/details/124335100 使用软件 QT 5.14.2下载地址&#xff1a;download.qt.io 选择版本&#xff1a;Qt 5.14.2 Qt 5.14.2百度网盘链接…

golang--函数栈

一、函数栈的组成结构&#xff08;栈帧&#xff09; 每个函数调用对应一个栈帧&#xff0c;包含以下核心部分&#xff1a; 1. 参数区 (Arguments) 位置&#xff1a;栈帧顶部&#xff08;高地址端&#xff09;内容&#xff1a; 函数调用时传入的参数按从右向左顺序压栈&#xff…

【FAQ】创建Dynamics 365 Sales环境

参考文章&#xff1a;5 分钟内安装 Dynamics 365 Sales 步骤 1&#xff1a;访问 Power Platform 管理中心 导航到make.powerapps.com&#xff0c;然后点击右上角的齿轮图标。选择管理中心&#xff0c;或者访问aka.ms/ppac访问 Power Platform 管理中心。 第 2 步&#xff1a…

【数据库】使用Sql Server将分组后指定字段的行数据转为一个字段显示,并且以逗号隔开每个值,收藏不迷路

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂》。 这是《Sql Server》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录前言示例数据集数…

7.项目起步(1)

1&#xff0c;项目起步-初始化项目并使用git管理创建项目并精细化配置src目录调整git 管理项目2项目起步-配置别名路径联想提示什么是别名路径联想提示如何进行配置 &#xff08;自动配置了&#xff09;{"compilerOptions" : {"baseUrl" : "./",…

【C++详解】深入解析继承 类模板继承、赋值兼容转换、派生类默认成员函数、多继承与菱形继承

文章目录一、继承概念二、继承定义定义格式继承后基类成员访问方式的变化类模板的继承三、基类和派⽣类间的转换(赋值兼容转换)四、继承中的作用域隐藏规则两道笔试常考题五、派生类的默认成员函数四个常见默认成员函数实现⼀个不能被继承的类六、继承与友元七、继承与静态成员…

加法器 以及ALU(逻辑算术单元)

加法器框架&#xff0c;首先介绍原理&#xff0c;然后引入一位加法器最后再引入多位加法器最后引入带符号的加法器这一节涉及到的硬件电路的知识理解就好&#xff0c;实在看不懂就跳过&#xff0c;但是封装以后的功能必须看懂。这是一个一般的加法过程涉及到的必要元素图中已经…

设计模式实战:自定义SpringIOC(亲手实践)

上一篇&#xff1a;设计模式实战&#xff1a;自定义SpringIOC&#xff08;理论分析&#xff09; 自定义SpringIOC&#xff08;亲手实践&#xff09; 上一篇文章&#xff0c;我们介绍了SpringIOC容器的核心组件及其作用&#xff0c;下面我们来动手仿写一个SpringIOC容器&#…