C++20中头文件ranges的使用

news2024/11/24 20:54:04

      <ranges>是C++20中新增加的头文件,提供了一组与范围(ranges)相关的功能,此头文件是ranges库的一部分。包括:

      1.concepts:

      (1).std::ranges::range:指定类型为range,即它提供开始迭代器和结束标记(it provides a begin iterator and an end sentinel)。

      (2).std::ranges::sized_range:指定range在恒定时间(constant time)内知道其大小。

      (3).std::ranges::contiguous_range:指定range的迭代器类型满足std::contiguous_iterator。

namespace {

struct SimpleRange { // a minimum range
    int* begin();
    int* end();
};

struct NotRange { // not a range: begin does not return an input_or_output_iterator
    void* begin();
    int* end();
};

} // namespace

int test_ranges_concepts()
{
#ifdef _MSC_VER
	static_assert(std::ranges::range<SimpleRange>);
	static_assert(!std::ranges::range<NotRange>);
#endif

	static_assert(std::ranges::sized_range<std::list<int>> and not std::ranges::sized_range<std::forward_list<int>>);

	static_assert(std::ranges::contiguous_range<const std::vector<int>> and not std::ranges::contiguous_range<std::list<int>>);

	return 0;
}

      2.classes: std::views是std::ranges::views的别名

      (1).std::ranges::subrange:将迭代器-标记对(iterator-sentinel pair)组合成一个视图(view)。

      (2).std::ranges::views::empty、std::ranges::empty_view:没有任何元素的空视图。

      (3).std::ranges::views::single、std::ranges::single_view:包含指定值的单个元素的视图。

      (4).std::ranges::views::iota、std::ranges::iota_view:由重复增加初始值生成的序列构成的视图。

      (5).std::ranges::views::istream、std::ranges::basic_istream_view:在相关输入流上连续应用运算符>>所获得的元素组成的视图。

      (6).std::ranges::views::all、std::ranges::views::all_t:包含range的所有元素的视图。

      (7).std::ranges::ref_view:其它range的元素的视图。

      (8).std::ranges::views::take、std::ranges::take_view:由另一个视图的前N​​个元素组成的视图。

      (9).std::ranges::owning_view:对某一range具有唯一所有权的视图。

      (10).std::ranges::views::drop、std::ranges::drop_view:由另一个视图的元素组成的视图,跳过前N个元素。

      (11).std::ranges::views::join、std::ranges::join_view:由展平(flattening)ranges视图获得的序列组成的视图。

      (12).std::ranges::views::counted:从迭代器和计数创建一个子range。

      (13).std::ranges::views::elements、std::ranges::elements_view:采用由类似元组的值和数字N组成的视图,并生成每个元组的第N个元素的视图。

int test_ranges_classes()
{
	// std::ranges::views == std::views
	// std::ranges::subrange
	const std::multimap<int, char> mm{ {1, 'a'}, {2, 'a'}, {1, 'c'}, {3, 'd'}, {1, 'e'}, {1, 'f'} };
	auto [first, last] = mm.equal_range(1);
	for (const auto& [_, v] : std::ranges::subrange(first, last))
		std::cout << v << ","; // a,c,e,f,
	std::cout << std::endl;

	// std::ranges::empty_view
	std::ranges::empty_view<long> e;
	static_assert(std::ranges::empty(e));
	static_assert(0 == e.size());
	static_assert(nullptr == e.data());
	static_assert(nullptr == e.begin());
	static_assert(nullptr == e.end());

	// std::ranges::single_view
	constexpr std::ranges::single_view sv1{ std::numbers::pi };
	static_assert(sv1);
	static_assert(not sv1.empty());
	std::cout << "data:" << *sv1.data() << ";begin:" << *sv1.begin() << ";size:" << sv1.size() << ";distance:" << std::distance(sv1.begin(), sv1.end()) << std::endl; // data:3.14159;begin:3.14159;size:1;distance:1

	std::ranges::single_view<std::tuple<int, double, std::string>> sv2{ {1, std::numbers::sqrt2, "^-^"} };
	std::cout << "value:" << std::get<0>(sv2[0]) << "," << std::get<1>(sv2[0]) << "," << std::get<2>(sv2[0]) << std::endl; // value:1,1.41421,^-^

	// std::ranges::views::iota/std::ranges::iota_view
	for (auto i : std::ranges::iota_view{ 1, 10 })
		std::cout << i << ' '; // 1 2 3 4 5 6 7 8 9
	std::cout << std::endl;

	for (auto i : std::ranges::views::iota(1, 10))
		std::cout << i << ' '; // 1 2 3 4 5 6 7 8 9
	std::cout << std::endl;

	// std::ranges::views::istream
	auto words = std::istringstream{ "today is yesterday's tomorrow" };
	for (const auto& s : std::views::istream<std::string>(words))
		std::cout << std::quoted(s, '/') << ' '; // /today/ /is/ /yesterday's/ /tomorrow/
	std::cout << '\n';

	// std::views::all
	const std::vector<int> vec{ 0, 1, 2, 3, 4, 5 };
	for (auto n : std::views::all(vec))
		std::cout << n << ' '; // 0 1 2 3 4 5
	std::cout << std::endl;

	// std::ranges::take_view,std::ranges::ref_view
	const std::string str{ "Messy_Test" };
	const std::ranges::take_view tv{ str, 5 };
	std::cout << "second element:" << *(tv.data()+1) << ",size:" << tv.size() << std::endl; // second element:e,size:5
	const std::ranges::ref_view rv{ tv };
	std::cout << "empty:" << rv.empty() << ",size:" << rv.size() << ",begin:" << *rv.begin() << ",end:" << *(rv.end() - 1) << ",data:" << rv.data() << std::endl; // empty:0,size:5,begin:M,end:y,data:Messy_Test
	for (const auto c : rv)
		std::cout << c; // Messy
	std::cout << std::endl;

	// std::ranges::owning_view
	using namespace std::literals;
	std::ranges::owning_view ov{ "Messy_Test"s }; // <== ov{std::string{"Messy_Test"}}
	assert(ov.empty() == false && ov.size() == 10 && ov.front() == 'M' && ov.back() == 't');

	// std::ranges::drop_view,std::views::drop
	const auto nums = { 1, 2, 3, 4, 5, 6, 7 };
	for (auto i : std::ranges::drop_view{ nums, 2 })
		std::cout << i << ' '; // 3 4 5 6 7
	std::cout << std::endl;

	for (auto i : nums | std::views::drop(3))
		std::cout << i << ' '; // 4 5 6 7
	std::cout << std::endl;;

	// std::ranges::join_view
	const std::vector<std::vector<int>> v{ {1, 2}, {3, 4, 5}, {6}, {7, 8, 9} };
	auto jv = std::ranges::join_view(v);
#ifdef __linux__
	for (int const e : jv)
		std::cout << e << ' ';
	std::cout << std::endl;
#endif

	// std::views::counted
	const int a[]{ 1, 2, 3, 4, 5, 6, 7 };
	for (int i : std::views::counted(a, 3))
		std::cout << i << ' '; // 1 2 3
	std::cout << std::endl;

	// std::views::elements
	const std::vector<std::tuple<int, char>> vt {{1, 'A'},{2, 'B'},{3, 'C'},{4, 'D'},{5, 'E'}};
	for (int const e : std::views::elements<0>(vt))
		std::cout << e << ' '; // 1 2 3 4 5
	std::cout << std::endl;

	for (char const e : vt | std::views::elements<1>)
		std::cout << e << ' '; // A B C D E
	std::cout << std::endl;

	return 0;
}

      执行结果如下图所示:

      3.customization point objects:

      (1).std::ranges::begin、std::ranges::cbegin:返回指向range开头的迭代器。

      (2).std::ranges::end、std::ranges::cend:返回指示range结束的哨兵(sentinel)。

      (3).std::ranges::rbegin、std::ranges::crbegin:返回range的反向迭代器。

      (4).std::ranges::rend、std::ranges::crend:返回range的反向结束迭代器。

      (5).std::ranges::size:返回等于range大小的整数。

      (6).std::ranges::ssize:返回等于range大小的有符号整数。

      (7).std::ranges::empty:检查range是否为空。

      (8).std::ranges::data、std::ranges::cdata:获取指向连续range开头的指针。

int test_ranges_customization_point_objects()
{
	// std::ranges::begin
	std::vector v{ 3, 1, 4, 9, 6};
	auto vi = std::ranges::begin(v);
	std::cout << *vi << std::endl; // 3
	*(++vi) = 66;
	std::cout << v[1] << std::endl; // 66

	// std::ranges::end
	vi = std::ranges::end(v);
	std::cout << *(vi-1) << std::endl; // 6
	*(--vi) = 88;
	std::cout << v[4] << std::endl; // 88

	for (auto vi = std::ranges::cbegin(v); vi != std::ranges::end(v); ++vi)
		std::cout << *vi << " "; // 3 66 4 9 88
	std::cout << std::endl;

	// std::ranges::rbegin
	auto vj = std::ranges::rbegin(v);
	std::cout << *vj << std::endl; // 88
	*(++vj) = 33;
	std::cout << v[3] << std::endl;

	// std::ranges::rend
	vj = std::ranges::rend(v);
	std::cout << *(vj-1) << std::endl; // 3
	*(--vj) = 99;
	std::cout << v[0] << std::endl; // 99

	// std::ranges::size
	std::cout << "size:" << std::ranges::size(v) << ",ssize:" << std::ranges::ssize(v) << std::endl; // size:5,ssize:5

	// std::ranges::empty
	std::cout << "v is empty:" << std::ranges::empty(v) << std::endl; // v is empty:0
	std::map<int, std::string> m{};
	std::cout << "m is empty:" << std::ranges::empty(m) << std::endl; // m is empty:1

	std::string str{ "hello world!" };
	std::ranges::data(str)[0] = 'H';
	std::cout << std::ranges::data(str) << std::endl; // Hello world!

	return 0;
}

      执行结果如下图所示:

      GitHub:https://github.com/fengbingchun/Messy_Test

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

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

相关文章

【WPF】中Dispatcher的DispatcherPriority参数使用

在 WPF 中&#xff0c;DispatcherPriority 参数用于指定通过 Dispatcher 调度的操作的执行优先级。加入 DispatcherPriority 参数的情况通常取决于你希望操作何时以及如何被执行。 1.Dispatcher的DispatcherPriority参数使用 以下是几种情况和示例说明&#xff1a; 1.1 需要…

量子纠错--shor‘s 码

定理1 (量子纠错的条件) C是一组量子编码&#xff0c;P是映射到C上的投影算子。假设是一个算子元素描述的量子操作&#xff0c;那么基于量子编码C&#xff0c;存在一个能对抗描述的噪声的纠错操作R的充要条件是 对某个复元素厄米矩阵成立。 将算子元素称为导致的错误。如果这样…

数字 图像处理算法的形式

一 基本功能形式 按图像处理的输出形式&#xff0c;图像处理的基本功能可分为三种形式。 1&#xff09;单幅图像 单幅图像 2&#xff09;多幅图像 单幅图像 3&#xff09;单&#xff08;或多&#xff09;幅图像 数字或符号等 二 几种具体算法形式 1.局部处理邻域对于任一…

第二单元历年真题整理

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 参考答案 1. A 2. A 3. A 4. D 5. D 6. D 解析&#xff1a; 栈和队列是两个不一样的结构&#xff0c;不能放在一起表示 7. B 8. C 解析&#xff1a; S --> A0 | B1 --> (S1 | 1) 0 | (S0 | 0)1 --> S10 | 10 | S…

Java程序员如何获得高并发经验?

高并发编程 提到并发编程很多人就会头疼了&#xff1b;首先就是一些基础概念&#xff1a;并发&#xff0c;并行&#xff0c;同步&#xff0c;异步&#xff0c;临界区&#xff0c;阻塞&#xff0c;非阻塞还有各种锁全都砸你脸上&#xff0c;随之而来的就是要保证程序运行时关键…

蓝桥杯题目理解

1. 一维差分 1.1. 小蓝的操作 1.1.1. 题目解析&#xff1a; 这道题提到了对于“区间”进行操作&#xff0c;而差分数列就是对于区间进行操作的好方法。 观察差分数列&#xff1a; 给定数列&#xff1a;1 3 5 2 7 1 差分数列&#xff1a;1 2 2 -3 5 6 题目要求把原数组全部…

Leetcode239. 滑动窗口最大值

问题描述&#xff1a; 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例 1&#xff1a; 输入&#xff1a;nums [1,3,…

c#子控件拖动父控件方法及父控件限在窗体内拖动

一、效果 拖放位置不超过窗体四边,超出后自动靠边停靠支持多子控件拖动指定控件拖放(含父控件或窗体)点击左上角logo弹出消息窗口(默认位置右下角)1.1 效果展示 1.2 关于MQTTnet(最新版v4.3.7.1207)实现在线客服功能,见下篇博文 https://github.com/dotnet/MQTTnet 网上…

7、哈希表

7、哈希表 哈希表最主要的作用就是把一个比较庞大的空间或者值域 映射到比较小的值域 (0-n) 就是将-10^9 ~10^9 映射到 0 ~10^5 一、存储结构 映射的方法可以是 h(x) x mod 10^5 但是这样映射会出现一个问题 可能会有重复的数字出现 所以就引出了两个方法 开放寻址法 和…

时间数据可视化基础实验(南丁格尔玫瑰图)——Python热狗大胃王比赛数据集

【实验名称】 实验一&#xff1a;时间数据的可视化 【实验目的】 1.掌握时间数据在大数据中的应用 2.掌握时间数据可视化图表表示 3. 利用python程序实现堆叠柱形图的可视化 【实验原理】 时间是一个非常重要的维度与属性。时间序列数据存在于社会的各个领域&#xff0c;如&a…

金融工程--pine-script 入门

背景 脚本基本组成 策略实现 实现马丁格尔策略 初始化变量&#xff1a;定义初始资本、初始头寸大小、止损百分比、止盈百分比以及当前资本和当前头寸大小等变量。 更新头寸&#xff1a;创建一个函数来更新头寸大小、止损价格和止盈价格。在马丁格尔策略中&#xff0c;每次亏…

若依框架篇-若依集成 X-File-Storage 框架(实现图片上传阿里云 OSS 服务器)、EasyExcel 框架(实现 Excel 数据批量导入功能)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 实现使用 Excel 文件批量导入 1.1 导入功能的前端具体实现 1.2 导入功能的后端具体实现 1.3 使用 EasyExcel 框架实现 Excel 读、写功能 1.4 将 Easy Excel 集成到…

npm、yarn、pnpm的workspaces使用

示例项目中总会遇到npm的packages中出现的workspaces键值对&#xff0c;自己的项目中没接触过这个东西&#xff0c;到底是什么&#xff1f;怎么用的&#xff1f;简单研究记录一下&#xff1a; abbrev是一个npm包&#xff0c;提供缩写展开功能。‌ 当你定义一个缩写后&#xff0…

mac电脑设置chrome浏览器语言切换为日语英语等不生效问题

在chrome中设置了语言&#xff0c;并且已经置顶了&#xff0c;但是不生效&#xff0c;在windows上直接有设置当前语言为chrome显示语言&#xff0c;但是mac上没有。 解决办法 在系统里面有一个单独给chrome设置语言的&#xff1a; 单独给它设定成指定的语言&#xff0c;然后重…

CTFHUB技能树之文件上传——双写后缀

开启靶场&#xff0c;打开链接&#xff1a; 直接指明是双写绕过方法 上传06shaungxie.php&#xff0c;内容如下&#xff1a; 这一步其实最好换成.png或者.jpg或者.gif这三个符合文件格式的要求后缀 用burp抓包改包&#xff1a; 将php改成pphphp后再“Forward”&#xff1a; 上传…

机房巡检机器人有哪些功能和作用

随着数据量的爆炸式增长和业务的不断拓展&#xff0c;数据中心面临诸多挑战。一方面&#xff0c;设备数量庞大且复杂&#xff0c;数据中心内服务器、存储设备、网络设备等遍布&#xff0c;这些设备需时刻保持良好运行状态&#xff0c;因为任何一个环节出现问题都可能带来严重后…

高边坡稳定安全监测预警系统解决方案

一、项目背景 高边坡的滑坡和崩塌是一种常见的自然地质灾害&#xff0c;一但发生而没有提前预告将给人民的生命财产和社会危害产生严重影响。对高边坡可能产生的灾害提前预警、必将有利于决策者采取应对措施、减少和降低灾害造成的损失。现有的高边坡监测技术有人工巡查和利用测…

设计一个html+css+js的注册页,对于注册信息进行合法性检测

综合使用HTML、JavaScript和CSS进行注册页面设计&#xff0c;实现以下若干功能&#xff1a; 注意整个页面的色调和美观使用FramesetTable布局&#xff08;div也可&#xff09;对用户ID和用户名、口令不符合条件及时判断对口令不一致进行及时判断&#xff08;34的及时判断&#…

【AI学习】Mamba学习(十三):简单了解S5模型,S5论文速读

学习了S4模型后&#xff0c;简单看一下S5模型。 来自两篇文章的摘要 苏神在文章《重温状态空间模型SSM&#xff1a;HiPPO的高效计算&#xff08;S4&#xff09;》中简单提到了S5模型&#xff1a; 由于 HiPPO 的推导是基于u(t)是一维函数进行的&#xff0c;所以到目前为止&am…

博弈论 C++

前置知识 若一个游戏满足&#xff1a; 由两名玩家交替行动在游戏进行的任意时刻&#xff0c;可以执行的合法行动与轮到哪位玩家无关不能行动的玩家判负 则称该游戏为一个公平组合游戏。 尼姆游戏&#xff08;NIM&#xff09;属于公平组合游戏&#xff0c;但常见的棋类游戏&…