探索 cartesian_product:更深入理解范围库

理解范围库中的cartesian_product适配器

  • 一、简介
  • 二、cartesian_product 适配器的动机
  • 三、将行为封装到算法中
  • 四、算法的局限性
  • 五、总结

一、简介

view::cartesian_product 适配器是range-v3 库一个新的组件。本文主要理解这个组件的功能以及它背后的设计理念,可以更好地掌握range库。虽然可以通过研究 zip 适配器来理解这些内容,但 cartesian_product 是一个全新的适配器,探索它既可以掌握range库,也可以学习新技术,一举两得。

为什么要花时间理解范围库呢?

因为范围是 STL 的未来。STL 是一个强大的工具,可以编写富有表现力的代码,而范围库是一个设计精良的库,它将 STL 的功能推向了更远。简而言之,学习范围库可以了解编写富有表现力的 C++ 代码的趋势。

二、cartesian_product 适配器的动机

cartesian_product 适配器的目的是遍历多个集合元素的所有可能组合。

为了避免引入业务逻辑,本文将使用一些简单的示例,但它在实际应用中非常有用,例如当对象具有版本时。在这种情况下,可能希望生成所有对象在所有可能日期上的组合。

为了说明问题,使用以下三个集合:

  • 一个包含数字的集合:

    std::vector<int> numbers = {3, 5, 12, 2, 7};
    
  • 一个包含字符串表示的常见聚会食物类型的集合:

    std::vector<std::string> dishes = {"pizzas", "beers", "chips"};
    
  • 一个包含字符串表示的聚会地点的集合:

    std::vector<std::string> places = {"London", "Paris", "NYC", "Berlin"};
    

现在,希望对这三个集合元素的所有可能组合执行一个操作,例如打印一个句子。
在这里插入图片描述

三、将行为封装到算法中

编写一个通用的函数,可以将一个函数应用于多个集合元素的所有可能组合。为了专注于算法的职责,这里省略了可变参数的内容:

template<typename Collection1, typename Collection2, typename Collection3, typename Function>
void cartesian_product(Collection1&& collection1, Collection2&& collection2, Collection3&& collection3, Function func)
{for (auto& element1 : collection1)for (auto& element2 : collection2)for (auto& element3 : collection3)func(element1, element2, element3);
}

这个函数可以完成任务。调用:

cartesian_product(numbers, dishes, places,[](int number, std::string const& dish, std::string const& place){ std::cout << "I took " << number << ' ' << dish << " in " << place << ".\n";});

四、算法的局限性

虽然看起来不错,但如果稍微改变一下需求,上面的代码就会失效。假设不再希望函数直接写入控制台,而是希望将各种组合输出到一个字符串容器中。

在这种情况下,无法使用上面的实现,因为它没有返回值。

实际上,上面的算法类似于 std::for_each 的所有可能组合版本,因为它遍历所有组合并应用一个函数。真正需要的是类似于 std::transform 的东西。

难道要重新编写一个新的 cartesian_product 函数,它接受一个输出集合和一个函数,就像 std::transform 一样吗?这感觉不对劲,不是吗?更希望将迭代职责从算法中分离出来。而 cartesian_product 适配器正是为此而生的。

cartesian_product 适配器在多个集合上构建一个视图,将其表示为一个包含所有可能组合的元组的范围。然后,函数需要接受一个包含其参数的元组。需要注意的是,最好直接获取参数,而不是通过元组。

以下是一个满足将句子输出到字符串容器需求的示例:

std::string meetupRecap(std::tuple<int, std::string, std::string> const& args)
{int number = std::get<0>(args);std::string const& dish = std::get<1>(args);std::string const& place = std::get<2>(args);std::ostringstream result;result << "I took " << number << ' ' << dish << " in " << place << '.';return result.str();
}std::vector<std::string> results;
transform(ranges::view::cartesian_product(numbers, dishes, places), std::back_inserter(results), meetupRecap);

同一个适配器也可以用于将输出写入控制台,而无需编写特定的算法:

void meetupRecapToConsole(std::tuple<int, std::string, std::string> const& args)
{int number = std::get<0>(args);std::string const& dish = std::get<1>(args);std::string const& place = std::get<2>(args);std::cout << "I took " << number << ' ' << dish << " in " << place << ".\n";
}for_each(ranges::view::cartesian_product(numbers, dishes, places), meetupRecapToConsole);

这个适配器有效地承担了生成所有可能元素组合的职责,从而能够重用常规算法,例如 for_eachtransform

五、总结

cartesian_product 适配器是范围库中一个强大的工具,它可以简化生成多个集合元素所有可能组合的过程。通过使用 cartesian_product 适配器,我们可以避免编写复杂的循环嵌套,从而提高代码的可读性和可维护性。

此外,cartesian_product 适配器还能够与其他范围库组件(如 transformfor_each)无缝衔接,进一步提升代码的灵活性和表达力。

虽然目前 cartesian_product 适配器使用元组来传递参数,但未来可能会引入更简洁的接口,例如直接传递参数而不使用元组。这将进一步简化代码编写,并使 cartesian_product 适配器更加易于使用。

cartesian_product 适配器是范围库中一个值得关注的组件,它可以帮助我们更高效地处理元素组合问题,并为编写更富有表现力的 C++ 代码提供新的思路。

在这里插入图片描述

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

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

相关文章

罗森伯格1800M 2000M 2400M 900M无源互调分析仪

在无线通信领域&#xff0c;频段是宝贵的资源&#xff0c;不同的通信系统通常会采用不同的频段以满足其传输需求。随着技术的发展&#xff0c;越来越多的通信系统被部署在各种频段上。为了准确、高效地测试和调试这些 信系统&#xff0c;各种测试设备也应运而生。源互调分析仪便…

Llama-3安装方法及应用

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

Stable Diffusion直接生成IP三视图,一天设计100个?

AI都能直接生成IP形象三视图了&#xff01; SD生成一个动物Q版IP三视图模型。标准的三视图&#xff0c;并且极富设计感&#xff0c;IP设计师的好帮手&#xff0c;用来辅助创意&#xff0c;建模参考。这个模型主要是动物类&#xff0c;一般不需堆叠复杂的质量词&#xff0c;直接…

资源付费系统小程序APP公众号h5源码

&#x1f510; 揭秘“资源付费系统”&#xff1a;知识、技能与价值的交汇点 &#x1f48e; &#x1f31f; 引言&#xff1a;为何资源需要付费&#xff1f; 在数字化时代&#xff0c;我们周围充斥着大量的信息。但并非所有信息都具有同等的价值。其中&#xff0c;那些经过精心…

入门 Axure RP 9 | 原型设计基础教程

选择正确的原型设计工具并非易事&#xff0c;Axure RP 9能够快速完成原型设计。原型设计是一种经过时间考验的方法&#xff0c;可以将你的设计快速放置在用户的设备并交到他们手中。替代Axure RP 9的原型设计工具即时设计是一个完全集成的协同设计工具&#xff0c;无需使用不同…

Vue3中使用深度选择器不起作用

问题&#xff1a; 想要给这个菜单设置高度100%&#xff0c;使用深度样式选择器无效 这样写无效 但是如下在控制台写是有效果的 解决&#xff1a; 参考 解决方法是给这个组件增加一个根元素&#xff0c;然后再使用深度选择器

【C语言】指针的指针使用场景

前言 C 语言中&#xff0c;比较难理解的就是指针&#xff0c;完全搞懂了指针&#xff0c;那么C语言算是入了门。 指针中比较难理解的概念&#xff1a; 指针的指针。 指针的指针&#xff0c;刚开始看到这个概念&#xff0c;感觉头疼。但是我们在程序里面应用一次就能搞懂。 本文…

如何合并pdf文件到一个pdf

在现代办公和学习中&#xff0c;PDF格式的文件因其跨平台兼容性和安全性得到了广泛应用。然而&#xff0c;有时我们需要将多个PDF文件合并成一个&#xff0c;以便于管理和分享。本文将详细介绍几种合并PDF的方法&#xff0c;帮助读者轻松完成PDF文件的合并工作。 首先通过浏览器…

运营商二要素核验-手机号机主姓名核验接口-运营商二要素核验接口

通过电信运营商验证手机号码与姓名是否一致。广泛用于实名注册、风控审核等场景&#xff0c;如电商、游戏、直播、金融等需要用户实名认证的场景。支持携号转网核验。 更新周期&#xff1a;联通T1 电信T3 移动T3~5 均为工作日 接口地址&#xff1a; https://www.wapi.cn/api_de…

24V转5V降压芯片AH8642A:高效稳定的电源转换解决方案

### 24V转5V降压芯片AH8642A&#xff1a;高效稳定的电源转换解决方案 在电子设备日益增多的今天&#xff0c;电源转换效率和稳定性成为了设计中的关键因素。AH8642A是一款专为24V转5V设计的降压芯片&#xff0c;它以其高效率、宽输入电压范围和稳定的输出电压在电源转换领域脱颖…

JAVA:通过电信ctg.ag.sdk从电信物联平台AIOT获取设备上报数据的简单示例

一、问题场景 物联设备比如NB设备通过NB协议将数据传到电信平台后&#xff0c;我们的应用服务如何从电信平台获取可用的上报数据。以下通过电信开发者平台提供的SDK来简单演示下整个过程。 二、使用电信 SDK进行开发 电信AIOT物联平台提供了两种方式获取平台数据&#xff0c…

C语言 指针——字符数组与字符指针:字符串的表示与存储

目录 字符串常量 字符串变量&#xff1f; 字符数组的定义和初始化 字符指针的定义和初始化 将字符指针指向一个字符串 用字符数组保存一个字符串 将字符指针指向一个字符数组 使用字符指针的基本原则 使用指针的基本原则 字符串常量 字符串变量&#xff1f;  C 语言…

40. 【Java教程】数据库编程

本小节我们将学习如何使用 Java 语言结合数据库进行编程。注意&#xff0c;学习本小节需要你有一定的 SQL 基础&#xff0c;了解 MySQL 数据库的 基础 CRUD 操作。 本小节我们将选择开源免费的 MySQL 5.7 作为数据库&#xff0c;可以去官网下载并安装 MySQL。 通过本小节的学…

AI预测福彩3D采取888=3策略+和值012路或胆码测试6月13日新模型预测第3弹

今天咱们继续验证新模型的8码定位3&#xff0c;目前新模型新算法已连续命中2次。咱们重点是预测8码定位3&#xff0b;和值012胆码。有些朋友看到我最近两篇文章没有给大家提供缩水后的预测详情&#xff0c;在这里解释下&#xff1a;其实我每篇文章中既有8码定位&#xff0c;也有…

数据库学霸笔记

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

【MySQL】性能分析

https://www.bilibili.com/video/BV1Kr4y1i7ru/?p78 查看执行频次 查看当前数据库的 INSERT, UPDATE, DELETE, SELECT 访问频次&#xff1a; SHOW GLOBAL STATUS LIKE Com_______; 或者 SHOW SESSION STATUS LIKE Com_______; 慢查询日志 慢查询日志记录了所有执行时间超过指…

【JVM】之常见面试题

文章目录 1.JVM中的内存区域划分2.JVM的类加载机制2.1 加载2.2 验证2.3 准备2.4 解析2.5 初始化2.6 类加载的时机 3 类加载器4.双亲委派模型5.JVM中的垃圾回收策略5.1 找谁是垃圾5.1.1 引用计数法5.1.2 可达性分析法 5.2 释放垃圾5.2.1 标记清除算法5.2.2 复制算法5.2.3 标记整…

CorelDRAW2024永久破解版下载安装全教程!

在设计领域&#xff0c;精准和专业是至关重要的要素。随着技术的飞速发展&#xff0c;设计师们对软件的选择也越发严苛。CorelDRAW 2024中文版及其2024终身永久版、破解版&#xff0c;因其强大的功能和便捷的使用体验&#xff0c;成为了设计师们的首选之一。本文将深入探讨这一…

网络编程入门

文章目录 网络编程入门计算机网络基础计算机网络发展史TCP/IP模型网络应用模式 基于HTTP协议的网络资源访问HTTP&#xff08;超文本传输协议&#xff09;JSON格式requests库 基于传输层协议的套接字编程TCP套接字UDP套接字 网络应用开发发送电子邮件发送短信 网络编程入门 计算…

大模型时代已至,产品经理如何紧跟时代步伐?

前言 在数字化浪潮的推动下&#xff0c;人工智能领域正迎来一场技术革命&#xff0c;而大模型技术的崛起无疑是这场革命中的明星。作为产品经理&#xff0c;我们不仅要洞察市场趋势&#xff0c;更要紧跟技术发展&#xff0c;以创新的思维和敏锐的洞察力&#xff0c;引领产品走…