C++23 views::chunk_by (P2443R1) 详解

文章目录

    • 引言
    • C++23 范围库概述
      • 范围视图(Range Views)
      • 范围算法(Range Algorithms)
      • 范围适配器(Range Adapters)
    • std::views::chunk_by 介绍
      • 基本概念
      • 特性
      • 使用场景
    • 示例代码
      • 简单示例
      • 自定义谓词示例
    • 总结

引言

在C++的发展历程中,每一个新版本都会带来一些令人期待的特性和改进。C++23作为C++20的增量更新,聚焦于简化代码、增强类型安全和填补功能缺口。其中,std::views::chunk_by 作为范围适配器的新成员,为我们处理数据序列提供了更加便捷和高效的方式。本文将详细介绍 std::views::chunk_by 的基本概念、特性、使用场景以及示例代码。

C++23 范围库概述

在深入了解 std::views::chunk_by 之前,我们先来简单回顾一下C++20引入的范围库(Ranges library)。范围库是C++20的一个主要组成部分,它提供了一种新的方法来处理容器中的元素序列,使得代码更加简洁和可读。范围库主要包含以下几个关键概念:

范围视图(Range Views)

范围视图提供了一种不修改原始数据的情况下,对容器进行变换、过滤和切片的能力。常见的视图包括 std::views::allstd::views::filterstd::views::transform 等。例如:

#include <iostream>
#include <vector>
#include <ranges>int main() {std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};auto even_numbers = vec | std::views::filter([](int x) { return x % 2 == 0; });auto squared = even_numbers | std::views::transform([](int x) { return x * x; });auto first_three = squared | std::views::take(3);for (int x : first_three) {std::cout << x << " ";}// 输出: 4 16 36 return 0;
}

范围算法(Range Algorithms)

C++20引入了新的范围版本的算法,这些算法可以直接在范围对象上操作,而不需要显式循环。例如 std::ranges::sortstd::ranges::find 等。示例如下:

#include <iostream>
#include <vector>
#include <ranges>int main() {std::vector<int> vec = {5, 3, 1, 4, 2};std::ranges::sort(vec);std::cout << "Sorted vector: ";for (int x : vec) {std::cout << x << " ";}// 输出: Sorted vector: 1 2 3 4 5 auto min_val = std::ranges::min(vec);std::cout << "\nMinimum value: " << min_val << std::endl;// 输出: Minimum value: 1 return 0;
}

范围适配器(Range Adapters)

范围适配器类似于视图,但它们通常用于创建新的范围对象。常见的适配器包括 std::ranges::views::joinstd::ranges::views::chunk_by_size 等。

std::views::chunk_by 介绍

基本概念

std::views::chunk_by 是C++23中引入的一个范围适配器,它接受一个视图和一个可调用对象(二元谓词),并通过在每对相邻元素之间拆分底层视图来生成一个子范围(块)的视图。对于这些元素,谓词返回 false。每对元素中的第一个元素属于前一个块,第二个元素属于下一个块。

在标题 <ranges> 中定义如下:

template< ranges::forward_range V, std::indirect_binary_predicate<iterator_t<V>, ranges::iterator_t<V>> Pred >requires ranges::view<V> && std::is_object_v<Pred>
class chunk_by_view: public ranges::view_interface<chunk_by_view<V, Pred>> (since C++23)
namespace views {inline constexpr /* unspecified */ chunk_by = /* 未指定 */ ;
} (since C++23)

特性

  • 谓词而非等价关系:与D语言的 chunkBy 不同,std::views::chunk_by 不要求谓词是一个等价关系。例如,D的 chunkBy 要求谓词满足自反性、对称性和传递性,而 std::views::chunk_by 则没有这个限制。
  • 不支持输入范围:由于 chunk_by 需要对相邻元素计算谓词,因此它要求底层范围是前向范围(forward range)。缓存元素不是一种可行的方法,主要原因在 [P2321R2] 的第4.3.4节中有讨论。
  • 范围属性:如果底层范围是双向范围(bidirectional range),则 chunk_by 也是双向范围;否则,它是前向范围。如果底层范围是通用范围(common range),则 chunk_by 也是通用范围。它永远不会是借用范围(borrowed range)或有大小范围(sized range)。
  • 缓存机制:类似于 splitchunk_by 在其 begin 中计算第一个范围的末尾并进行缓存,以满足摊销的 O ( 1 ) O(1) O(1) 要求。这意味着它不支持常量迭代。

使用场景

std::views::chunk_by 适用于需要将一个序列按照某种规则进行分组的场景。例如,将一个整数序列按照奇偶性进行分组,或者将一个字符串序列按照长度进行分组等。

示例代码

简单示例

#include <iostream>
#include <vector>
#include <ranges>
#include <fmt/core.h>int main() {std::vector<int> v = {1, 2, 2, 3, 0, 4, 5, 2};fmt::print("{}\n", v | std::views::chunk_by(std::ranges::less_equal{}));   // [[1, 2, 2, 3], [0, 4, 5], [2]]return 0;
}

在这个示例中,我们使用 std::views::chunk_bystd::ranges::less_equal{} 谓词将整数序列 v 进行分组。当相邻元素不满足小于等于关系时,就会进行分组。

自定义谓词示例

#include <iostream>
#include <vector>
#include <ranges>
#include <fmt/core.h>int main() {std::vector<int> v = {1, 3, 5, 2, 4, 6, 7, 9};auto is_odd = [](int x) { return x % 2 == 1; };auto chunked = v | std::views::chunk_by([&is_odd](int a, int b) { return is_odd(a) == is_odd(b); });for (const auto& chunk : chunked) {for (int x : chunk) {std::cout << x << " ";}std::cout << std::endl;}return 0;
}

在这个示例中,我们自定义了一个谓词 is_odd 来判断一个数是否为奇数。然后使用 std::views::chunk_by 将整数序列按照奇偶性进行分组。

总结

std::views::chunk_by 是C++23范围库中一个非常实用的范围适配器,它为我们处理数据序列提供了更加灵活和高效的方式。通过使用 std::views::chunk_by,我们可以轻松地将一个序列按照某种规则进行分组,而不需要手动编写复杂的循环和逻辑。同时,范围库的惰性求值特性也使得代码更加高效,避免了不必要的计算和内存消耗。在实际开发中,我们可以根据具体的需求灵活运用 std::views::chunk_by 来简化代码,提高开发效率。

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

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

相关文章

零碳园区能源系统-多能互补体系

构建以可再生能源为核心的零碳园区能源系统&#xff0c;需整合光储直柔、光伏发电、微电网、氢能与储能技术&#xff0c;通过多能协同与智能调控实现能源生产、存储、消费全链条优化。以下是系统性实施方案&#xff1a; 一、系统架构设计 1. 多能互补体系 &#xff08;图示&a…

elastic search学习

首先在自己电脑上安装elastic search。安装成功后&#xff0c;查看ES是否启动成功。 安装过程参考&#xff1a;ElasticSearch入门1: mac 安装 - 霜井 - 博客园 安装完成后&#xff0c;直接执行bin目录中的elastic search命令后&#xff0c;就可以启动成功&#xff01; 在网页…

mysql8常用sql语句

查询结果带行号 -- 表名为 mi_user&#xff0c; 假设包含列 id &#xff0c;address SELECT ROW_NUMBER() OVER (ORDER BY id) AS row_num, t.id, t.address FROM mi_user t ; SELECT ROW_NUMBER() OVER ( ) AS row_num, t.id, t.address FROM mi_user t ; 更新某列数…

Memcached 服务搭建和集成使用的详细步骤示例

以下是 Memcached 服务搭建和集成使用的详细步骤示例&#xff1a; 一、搭建 Memcached 服务 安装 Memcached Linux 系统 yum 安装&#xff1a;执行命令 yum install -y memcached memcached-devel。源码安装 下载源码&#xff1a;wget http://www.memcached.org/files/memcach…

2. 盒模型/布局模块 - 响应式产品展示页_案例:电商产品网格布局

2. 盒模型/布局模块 - 响应式产品展示页 案例&#xff1a;电商产品网格布局 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><style type"text/css">:root {--primary-color…

Go基于plugin的热更新初体验

背景 对于一个部署在生产环境的项目来说&#xff0c;我们希望当代码出现bug的时候&#xff0c;可以不用重启进程而达到动态修改代码的目的—— 这就是代码热部署&#xff01; 使用java做游戏服务器&#xff0c;最大的好处是&#xff0c;当代码出现bug&#xff0c;可以直接热…

【RabbitMQ】工作队列和发布/订阅模式的具体实现

文章目录 建立连接工作队列模式实现创建队列和交换机生产者代码消费者代码运行程序启动消费者启动生产者 发布/订阅模式实现创建队列和交换机生产者代码创建交换机声明两个队列绑定队列和交换机发送消息完整代码 消费者代码完整代码 运行程序启动生产者启动消费者 建立连接 我…

Codeforces Round 998 (Div. 3)

A. Fibonacciness 题目大意 给你四个数字abde&#xff0c;让你找到一个中间值c&#xff0c;问 a b c a b c abc &#xff0c; b c d b c d bcd &#xff0c; c d e c d e cde 最多能有几个式子成立 解题思路 显然最多就六种情况&#xff0c;暴力枚举即可 代…

火山引擎发展初始

火山引擎是字节跳动旗下的云计算服务品牌&#xff0c;其云服务业务的启动和正式商业化时间线如下&#xff1a; 1. **初期探索&#xff08;2020年之前&#xff09;** 字节跳动在早期为支持自身业务&#xff08;如抖音、今日头条等&#xff09;构建了强大的基础设施和技术中…

【认知思维】光环效应:第一印象的持久力量

什么是光环效应 光环效应&#xff08;Halo Effect&#xff09;是指人们倾向于让对某人或某物的一个显著特质的印象影响对其他特质的评价的认知偏差。简单来说&#xff0c;当我们对某人的一个特质&#xff08;如外表、智力或某项技能&#xff09;形成积极印象时&#xff0c;我们…

Java Solon v3.3.0 发布(国产优秀应用开发基座)

Solon 框架&#xff01; Solon 是新一代&#xff0c;Java 企业级应用开发框架。从零开始构建&#xff08;No Java-EE&#xff09;&#xff0c;有灵活的接口规范与开放生态。采用商用友好的 Apache 2.0 开源协议&#xff0c;是“杭州无耳科技有限公司”开源的根级项目&#xff…

力扣-104.二叉树的最大深度

题目描述 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 class Solution { public:int maxDepth(TreeNode* root) {if(!root){return 0;}return max(maxDepth(root->left), maxDepth(root->…

单反和无反(私人笔记)

① 单反相机&#xff1a; 定义&#xff1a; 单反相机&#xff08;Single-Lens Reflex&#xff0c;SLR&#xff09;是一种带有反光镜结构的数码相机。光线通过镜头进入后&#xff0c;先被反光镜反射到五棱镜/五面镜&#xff0c;再通过取景器进入人眼。按下快门时&#xff0c;反…

超详细讲解C语言转义字符\a \b \r \t \? \n等等

转义字符 C语言有一组字符很特殊&#xff0c;叫做转义字符&#xff0c;顾名思义&#xff0c;改变原来的意思的字符。 1 \? ??)是一个三字母词&#xff0c;在以前的编译器它会被编译为] (??会被编译为[ 因此在以前输入(are you ok ??)就会被编译为are you ok ] 解决这个…

Java Spring MVC -01

SpringMVC 是一种基于 的实现 MVC 设计模式的请求驱动类型的轻量级 Web 框架&#xff0c;属于 Spring FrameWork 的后续产品&#xff0c;已经融合在 Spring Web Flow 中。 First:SpringMVC-01-SpringMVC 概述 SpringMVC 是 Spring 框架的一个模块&#xff0c;用于构建 Web 应…

Spring MessageSource 详解:如何在国际化消息中传递参数

在开发多语言应用程序时,Spring 的 MessageSource 是处理国际化(i18n)文本的核心组件。它允许我们根据用户的 Locale (区域设置) 显示不同的消息。然而,很多时候我们的消息并不是静态的,而是需要包含动态数据,比如用户名、数量、文件名等。这时,我们就需要在获取国际化消…

Datawhale 5月llm-universe 第1次笔记

课程地址&#xff1a;GitHub - datawhalechina/llm-universe: 本项目是一个面向小白开发者的大模型应用开发教程&#xff0c;在线阅读地址&#xff1a;https://datawhalechina.github.io/llm-universe/ 难点&#xff1a;配置conda环境变量 我用的vscode github方法 目录 重要…

基于Java的家政服务平台设计与实现(代码+数据库+LW)

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本家政服务平台就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&a…

Android中LinearLayout线性布局使用详解

Android中LinearLayout线性布局使用详解 LinearLayout&#xff08;线性布局&#xff09;是Android中最基础、最常用的布局之一&#xff0c;它按照水平或垂直方向依次排列子视图。 基本特性 方向性&#xff1a;可以设置为水平(horizontal)或垂直(vertical)排列权重&#xff1…

LVS+keepalived实战案例

目录 部署LVS 安装软件 创建VIP 创建保存规则文件 给RS添加规则 验证规则 部署RS端 安装软件 页面内容 添加VIP 配置系统ARP 传输到rs-2 客户端测试 查看规则文件 实现keepalived 编辑配置文件 传输文件给backup 修改backup的配置文件 开启keepalived服务 …