C++标准模板(STL)- 迭代器库 - 流迭代器- 写入 std::basic_ostream 的输出迭代器(二)

迭代器库-流迭代器

 

迭代器库提供了五种迭代器的定义,同时还提供了迭代器特征、适配器及相关的工具函数。

迭代器分类

迭代器共有五 (C++17 前)六 (C++17 起)种:遗留输入迭代器 (LegacyInputIterator) 、遗留输出迭代器 (LegacyOutputIterator) 、遗留向前迭代器 (LegacyForwardIterator) 、遗留双向迭代器 (LegacyBidirectionalIterator) 、遗留随机访问迭代器 (LegacyRandomAccessIterator) ,及 遗留连续迭代器 (LegacyContiguousIterator) (C++17 起)。

迭代器的分类的依据并不是迭代器的类型,而是迭代器所支持的操作。换句话说,某个类型只要支持相应的操作,就可以作为迭代器使用。例如,完整对象类型指针支持所有遗留随机访问迭代器 (LegacyRandomAccessIterator) 要求的操作,于是任何需要遗留随机访问迭代器 (LegacyRandomAccessIterator) 的地方都可以使用指针。

迭代器的所有类别(除了遗留输出迭代器 (LegacyOutputIterator) 和遗留连续迭代器 (LegacyContiguousIterator) )能组织到层级中,其中更强力的迭代器类别(如遗留随机访问迭代器 (LegacyRandomAccessIterator) )支持较不强力的类别(例如遗留输入迭代器 (LegacyInputIterator) )的所有操作。若迭代器落入这些类别之一且亦满足遗留输出迭代器 (LegacyOutputIterator) 的要求,则称之为可变 迭代器并且支持输入还有输出。称非可变迭代器为常迭代器。

流迭代器- 写入 std::basic_ostream 的输出迭代器

std::ostream_iterator
template< class T,

          class CharT = char,
          class Traits = std::char_traits<CharT> >
class ostream_iterator : public std::iterator<std::output_iterator_tag,

                                              void, void, void, void>
(C++17 前)
template< class T,

          class CharT = char,
          class Traits = std::char_traits<CharT>>

class ostream_iterator;
(C++17 起)

std::ostream_iterator 是单趟遗留输出迭代器 (LegacyOutputIterator) ,用 operator<< 写入相继 T 类型对象到为之创建迭代器的 std::basic_ostream 对象。每次写操作后写入可选的分隔字符串。写操作在赋值给迭代器时(无论是否解引用)进行。自增 std::ostream_iterator 是无操作。

典型实现中, std::ostream_iterator 仅有的数据成员是指向关联 std::basic_ostream 的指针和指向分隔字符串首字符的指针。

写入字符时, std::ostreambuf_iterator 更有效率,因为它避免对每个字符构造并析构一次 sentry 对象的开销。

成员类型

成员类型定义
iterator_categorystd::output_iterator_tag
value_typevoid
difference_typevoid
pointervoid
referencevoid
char_typeCharT
traits_typeTraits
ostream_typestd::basic_ostream<CharT, Traits>

要求通过从 std::iterator<std::output_iterator_tag, void, void, void, void> 继承获得成员类型 iterator_categoryvalue_typedifference_typepointerreference

(C++17 前)

写对象到关联的输出序列

std::ostream_iterator<T,CharT,Traits>::operator=

ostream_iterator& operator=( const T& value );

插入 value 到关联的流,然后插入分隔符,若在构造时指定它。

out_stream 是指向关联 std::basic_ostream 的指针而 delim 是在此对象构造时指定的分隔符,则效果等价于

*out_stream << value;
if(delim != 0)
    *out_stream << delim;
return *this;

参数

value-要插入的对象

返回值

*this

注意

T 能是任何拥有用户定义 operator<< 的类。

无操作

std::ostream_iterator<T,CharT,Traits>::operator*

ostream_iterator& operator*();

不做任何事,提供此函数以满足遗留输出迭代器 (LegacyOutputIterator) 的要求。

它返回迭代器自身,这使得可以用诸如 *iter = value 的代码输出(插入)值到底层的流。

参数

(无)

返回值

*this

无操作

std::ostream_iterator<T,CharT,Traits>::operator++

ostream_iterator& operator++();

ostream_iterator& operator++( int );

不做任何事。提供这些运算符以满足遗留输出迭代器 (LegacyOutputIterator) 的要求。它们使得表达式 *iter++=value 和 *++iter=value 可用于输出(插入)值到底层的流。

参数

(无)

返回值

*this

调用示例

#include <iostream>
#include <sstream>
#include <iterator>
#include <numeric>
#include <algorithm>struct Cell
{int x;int y;Cell() = default;Cell(int a, int b): x(a), y(b) {}Cell(const Cell &cell){x = cell.x;y = cell.y;}Cell(Cell &cell){x = cell.x;y = cell.y;cell.x = 0;cell.y = 0;}Cell &operator +=(const Cell &cell){x += cell.x;y += cell.y;return *this;}Cell &operator +(const Cell &cell){x += cell.x;y += cell.y;return *this;}Cell &operator *(const Cell &cell){x *= cell.x;y *= cell.y;return *this;}Cell &operator ++(){x += 1;y += 1;return *this;}bool operator <(const Cell &cell) const{if (x == cell.x){return y < cell.y;}else{return x < cell.x;}}bool operator ==(const Cell &cell) const{return x == cell.x && y == cell.y;}
};std::ostream &operator<<(std::ostream &os, const Cell &cell)
{os << "{" << cell.x << "," << cell.y << "}";return os;
}std::istream &operator>>(std::istream &is, Cell &cell)
{is >> cell.x;is >> cell.y;return is;
}// 定义一个简单的迭代器适配器
template<typename _Iterator>
class move_iterator : public std::move_iterator<_Iterator>
{
public:// 使用基类的构造函数using std::move_iterator<_Iterator>::move_iterator;// 可以在此添加其他成员函数,如有需要
};template< class BDIter >
void alg(BDIter, BDIter, std::input_iterator_tag)
{//遗留输入迭代器std::cout << "alg() called for input iterator" << std::endl;
}template< class BDIter >
void alg(BDIter, BDIter, std::output_iterator_tag)
{//遗留输出迭代器std::cout << "alg() called for output iterator" << std::endl;
}template< class BDIter >
void alg(BDIter, BDIter, std::forward_iterator_tag)
{//遗留向前迭代器std::cout << "alg() called for forward iterator" << std::endl;
}template< class BDIter >
void alg(BDIter, BDIter, std::bidirectional_iterator_tag)
{//遗留双向迭代器std::cout << "alg() called for bidirectional iterator" << std::endl;
}template <class RAIter>
void alg(RAIter, RAIter, std::random_access_iterator_tag)
{//遗留随机访问迭代器std::cout << "alg() called for random-access iterator" << std::endl;
}template< class Iter >
void alg(Iter first, Iter last)
{alg(first, last,typename std::iterator_traits<Iter>::iterator_category());
}int main()
{std::istringstream istringstream("1 2 3 4 5 6 7 8 9 10");std::cout << "partial_sum Cell: ";std::partial_sum(std::istream_iterator<Cell>(istringstream),std::istream_iterator<Cell>(),std::ostream_iterator<Cell>(std::cout, " "));std::cout << std::endl;std::istringstream istringstream2("1 2 3 4 5 6 7 8 9 10");std::cout << "The first Cell cell.x + cell.y > 12 is ";std::istringstream str2("1 2 3 4 5 6 7 8 9 10");auto function = [](const Cell & cell){Cell cellt = cell;cellt += cell;return cellt;};std::ostream_iterator<Cell> ostream_iterator1(std::cout, ", ");std::fill_n(ostream_iterator1, 5, function(Cell{101, 101}));std::cout << std::endl;std::ostream_iterator<Cell> ostream_iterator2(std::cout);*ostream_iterator2++ = Cell{103, 103};std::cout << std::endl;alg(ostream_iterator2, ostream_iterator2);return 0;
}

输出

partial_sum Cell: {1,2} {4,6} {9,12} {16,20} {25,30}
The first Cell cell.x + cell.y > 12 is {7,8}
alg() called for input iterator
{7,8} == {5,6}  false
{7,8} != {5,6}  true
istream_iterator2: {7,8}
{7,8} == {7,8}  false
{7,8} != {7,8}  true

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

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

相关文章

网络io与select,poll,epoll

前言 网络 IO&#xff0c;会涉及到两个系统对象&#xff0c;一个是用户空间调用 IO 的进程或者线程&#xff0c;另一个是内核空间的内核系统&#xff0c;比如发生 IO 操作 read 时&#xff0c;它会经历两个阶段&#xff1a; 1. 等待数据准备就绪 2. 将数据从内核拷贝到进程或…

网络编程常见问题

1、TCP状态迁移图 2、TCP三次握手过程 2.1、握手流程 1、TCP服务器进程先创建传输控制块TCB&#xff0c;时刻准备接受客户进程的连接请求&#xff0c;此时服务器就进入了LISTEN&#xff08;监听&#xff09;状态&#xff1b; 2、TCP客户进程也是先创建传输控制块TCB&#xff…

WebSockets 完全指南:在 Postman 中测试实时通信

标题&#xff1a;WebSockets 完全指南&#xff1a;在 Postman 中测试实时通信 摘要 Postman 是 API 开发者广泛使用的工具&#xff0c;支持 RESTful API 的测试和调试。随着实时通信的兴起&#xff0c;WebSockets 协议变得日益重要。本文将详细介绍如何在 Postman 中测试 Web…

改进经验模态分解方法-通过迭代方式(IMF振幅加权频率,Python)

一种新颖的改进经验模态分解方法-通过迭代方式&#xff08;IMF振幅加权频率&#xff09;有效缓解了模态混叠缺陷&#xff0c;以后慢慢讲&#xff0c;先占坑。 import numpy as np import matplotlib.pyplot as plt import os import seaborn as sns from scipy import stats i…

【python学习】bytearray 数组

在Python中&#xff0c;bytearray 是一个可变序列&#xff0c;用于表示一个字节数组。与不可变的 bytes 类型相比&#xff0c;bytearray 允许你修改其内容。你可以通过索引来访问和修改 bytearray 中的元素&#xff0c;也可以添加或删除元素。 使用 bytearray 的一些示例&…

C语言图书管理系统控制台程序

程序示例精选 C语言图书管理系统控制台程序 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对《C语言图书管理系统控制台程序》编写代码&#xff0c;代码整洁&#xff0c;规则&#xff0c;易读…

740. 删除并获得点数(leetcode)

740. 删除并获得点数&#xff08;leetcode&#xff09; 题目描述 给你一个整数数组 nums &#xff0c;你可以对它进行一些操作。每次操作中&#xff0c;选择任意一个 nums[i] &#xff0c;删除它并获得 nums[i] 的点数。之后&#xff0c;你必须删除 所有 等于 nums[i] - 1 和 …

目标检测算法用一个案例详细讲解

学习目标&#xff1a; 目标检测算法用一个案例详细讲解 学习内容&#xff1a; 主要以YOLO为例 YOLO 工作流程 输入图像&#xff1a; 首先&#xff0c;输入一张图像&#xff0c;该图像将被调整为固定大小&#xff08;如 416x416&#xff09;。网格划分&#xff1a; 图像被划分…

加密与安全_三种方式实现基于国密非对称加密算法的加解密和签名验签

文章目录 国际算法基础概念常见的加密算法及分类签名和验签基础概念常见的签名算法应用场景 国密算法对称加密&#xff08;DES/AES⇒SM4&#xff09;非对称加密&#xff08;RSA/ECC⇒SM2&#xff09;散列(摘要/哈希)算法&#xff08;MD5/SHA⇒SM3&#xff09; Code方式一 使用B…

智慧园区综合平台解决方案PPT(75页)

## 智慧园区的理解 ### 从园区1.0到园区4.0的演进 1. 园区1.0&#xff1a;以土地经营为主&#xff0c;成本驱动&#xff0c;提供基本服务。 2. 园区2.0&#xff1a;服务驱动&#xff0c;关注企业成长&#xff0c;提供增值服务。 3. 园区3.0&#xff1a;智慧型园区&#xff…

机器学习引领教育革命:智能教育的新时代

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀目录 &#x1f4d2;1. 引言&#x1f4d9;2. 机器学习在教育中的应用&#x1f31e;个性化学习&#x1f319;评估与反馈的智能化⭐教学资源的优…

spring-boot-configuration-processor注释处理器

开源项目SDK&#xff1a;https://github.com/mingyang66/spring-parent 个人文档&#xff1a;https://mingyang66.github.io/raccoon-docs/#/ spring-boot-configuration-processor是springboot提供的一个注释处理器&#xff08;annotation processor&#xff09;,它用于在编译…

Python多线程Concurrent

背景 从 Python3.2 开始&#xff0c;标准库为我们提供了 concurrent.futures 模块&#xff0c;它提供了 ThreadPoolExecutor 和 ProcessPoolExecutor两个类&#xff0c;实现了对 threading 和 multiprocessing 的进一步抽象&#xff08;这里主要关注线程池&#xff09;&#x…

STC89C52RC单片机设计的FM收音机+自动搜台+存储电台(程序+原理图+PCB)

资料下载地址&#xff1a;STC89C52RC单片机设计的FM收音机自动搜台存储电台&#xff08;程序原理图PCB) 1、实物图 2、部分程序 #include <reg52.h> #include "tea5767.h" #include "delay.h" #include "lcd1602.h" //K1:上一台 K2:下一…

mac电脑游戏推荐:NBA 2K24 街机版下载

NBA 2K24 街机版是一款由2K Sports开发并发行的篮球游戏&#xff0c;属于著名的NBA 2K系列。这款游戏为玩家提供了与NBA联赛中真实球员和球队互动的机会&#xff0c;体验篮球比赛的激情与紧张。街机版的NBA 2K24通常会在游戏厅、商场等公共场所设置&#xff0c;供玩家投币游玩。…

ubuntu server的安装

官网&#xff1a;https://ubuntu.com/ 点击 Get Ubuntu,选择Server&#xff0c;点击Get Ubuntu Server,下载iso到本地。 相关资料&#xff1a; Ubuntu Server 20.04详细安装教程虚拟机安装 Ubuntu

c++重载(运算符)

1&#xff09;C入门级小知识&#xff0c;分享给将要学习或者正在学习C开发的同学。 2&#xff09;内容属于原创&#xff0c;若转载&#xff0c;请说明出处。 3&#xff09;提供相关问题有偿答疑和支持。 对于系统的所有操作符&#xff0c;一般情况下&#xff0c;只支持基本数…

Android Gradle 开发与应用 (二): Android 项目结构与构建配置

目录 1. Android 项目的 Gradle 文件结构 1.1 项目根目录 1.2 模块目录 2. Gradle 构建配置详解 2.1 配置 Android 项目的 build.gradle 2.2 配置模块的 build.gradle 2.3 使用 productFlavors 管理多版本应用 2.4 使用 buildConfigField 注入构建常量 在 Android 开发…

AWTK 用 icon_at 属性设置图标位置

1. style 在 style 文件中通过 icon_at 属性设置图标位置。 <style name"right_bottom" icon_at"right_bottom"><normal icon"unchecked_right_bottom" /><pressed icon"unchecked_right_bottom" /><over i…

redis实战-短信登录

基于session的登录流程 session的登录流程图 1. 发送验证码 用户在提交手机号后&#xff0c;会校验手机号是否合法&#xff0c;如果不合法&#xff0c;则要求用户重新输入手机号 如果手机号合法&#xff0c;后台此时生成对应的验证码&#xff0c;同时将验证码进行保存&#x…