当前位置: 首页 > backend >正文

istringstream的简化源码详解


一、成员变量与核心逻辑

1.1 数据成员
protected:std::istream* stream;  // 输入流指针(绑定到istream对象)T value;               // 当前缓存值(存储最近读取的数据)bool end_marker;       // 流结束标志(EOF或读取失败时标记)
  • 作用
    • stream 绑定输入流(如 cin 或文件流),通过指针管理生命周期
    • value 缓存当前读取值,遵循STL输入迭代器单次只读特性
    • end_marker 标记流是否可继续读取,与 streamgood()/eof() 状态关联
1.2 read() 方法
void read() {end_marker = (*stream) ? true : false;if (end_marker) {*stream >> value;          // 尝试提取数据end_marker = (*stream) ? true : false;  // 二次验证流状态}if (!end_marker) {stream = nullptr;         // 标记流失效}
}
  • 关键逻辑
    1. 初始检查流有效性(隐式调用 operator bool() 判断 goodbit
    2. 若有效则尝试读取数据到 value,此时可能触发流错误标志(如类型不匹配)
    3. 再次验证流状态,处理中途失败的情况
    4. 流失效时置空指针,与结束迭代器状态对齐

二、构造函数与迭代器初始化

2.1 默认构造函数
istreamIterator() : stream(nullptr), end_marker(true) {}
  • 作用:创建流结束迭代器(类似 istream_iterator<T>()
  • 特点
    • stream=nullptr 明确标识结束状态
    • end_marker=true 确保与有效迭代器比较时能正确判断终止条件
2.2 绑定输入流的构造函数
explicit istreamIterator(std::istream& s) : stream(&s), end_marker(false) {read();  // 初始化时立即读取首个值
}
  • 特点
    • 构造时立即调用 read(),确保首次解引用即有有效值
    • 与STL的 istream_iterator<T>(istream) 行为一致,触发首次数据读取
    • explicit 禁止隐式类型转换,避免误用

三、迭代器操作符重载

3.1 解引用操作符
reference operator*() const { if (!stream) throw std::logic_error("Dereference on end iterator");return value; 
}
  • 行为
    • 返回当前缓存值的常量引用,符合输入迭代器只读特性
    • 安全性检查防止对结束迭代器解引用(STL标准行为未定义)
3.2 递增操作符
// 前置递增
istreamIterator& operator++() {if (!stream) throw std::logic_error("Increment on end iterator");read();return *this;
}// 后置递增
istreamIterator operator++(int) {istreamIterator tmp = *this;++(*this);return tmp;
}
  • 关键逻辑
    • 每次递增都会调用 read() 更新 valueend_marker
    • 后置递增返回旧值的拷贝,与STL迭代器行为一致
    • 前置版本效率更高(避免临时对象复制)

四、迭代器比较与流结束判断

4.1 相等运算符
friend bool operator==(const istreamIterator& x, const istreamIterator& y) {// 两个都是结束迭代器if (x.stream == nullptr && y.stream == nullptr) return true;  // 同一流且同为结束状态if (x.stream == y.stream && x.end_marker == y.end_marker) return true;// 一方是结束迭代器,另一方已读到结束return (x.stream == nullptr && y.end_marker) || (y.stream == nullptr && x.end_marker);
}
  • 比较规则
    1. 两个结束迭代器等价(stream=nullptr
    2. 同一流的两个迭代器需满足相同的结束状态
    3. 混合比较时需匹配"有效迭代器到结束"的过渡状态
4.2 不等运算符
friend bool operator!=(const istreamIterator& x, const istreamIterator& y) {return !(x == y);
}
  • 实现:直接复用 operator== 的结果,避免逻辑重复

五、模板类型定义与STL兼容性

typedef std::input_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef const T* pointer;
typedef const T& reference;
  • 作用
    • 定义迭代器类型特征,确保与STL算法(如 copyaccumulate)兼容
    • const 修饰符强制实现只读语义,防止意外修改

六、整体代码

#include <iostream>
#include <iterator>template <class T, class Distance = ptrdiff_t>
class istreamIterator {
protected:std::istream* stream;  // 输入流指针T value;               // 当前缓存值bool end_marker;        // 流结束标志// 核心数据读取方法void read() {end_marker = (*stream) ? true : false;if (end_marker) {*stream >> value;          // 尝试提取数据end_marker = (*stream) ? true : false;  // 验证提取结果}if (!end_marker) {stream = nullptr;         // 标记流失效}}public:// 类型定义typedef std::input_iterator_tag iterator_category;typedef T value_type;typedef Distance difference_type;typedef const T* pointer;typedef const T& reference;// 构造函数istreamIterator() : stream(nullptr), end_marker(true) {}explicit istreamIterator(std::istream& s) : stream(&s), end_marker(false) { read(); }// 禁用拷贝istreamIterator(const istreamIterator&) = delete;istreamIterator& operator=(const istreamIterator&) = delete;// 解引用reference operator*() const { if (!stream) throw std::logic_error("Dereference on end iterator");return value; }pointer operator->() const { return &(operator*()); }// 递增操作符istreamIterator& operator++() {if (!stream) throw std::logic_error("Increment on end iterator");read();return *this;}istreamIterator operator++(int) {istreamIterator tmp = *this;++(*this);return tmp;}// 比较运算符friend bool operator==(const istreamIterator& x, const istreamIterator& y) {return (x.stream == y.stream) || (!x.stream && y.end_marker) || (!y.stream && x.end_marker);}friend bool operator!=(const istreamIterator& x, const istreamIterator& y) { return !(x == y); }
};
http://www.xdnf.cn/news/5785.html

相关文章:

  • 热部署与双亲委派
  • pclinuxos系统详解
  • 应急响应靶机——WhereIS?
  • CRM和SCRM有什么区别
  • python实现usb热插拔检测(windows)
  • Android Framework
  • LWIP传输层协议笔记
  • Git 用法总结
  • 微信小程序原生swiper高度自适应图片,不同屏幕适配,正方形1:1等比例图片轮播
  • E+H流量计与Profibus DP主站转Modbus RTU/TCP网关通讯
  • DeepSeek新玩法: RAG Chatbot 3.0测试人的新大脑
  • 深入探讨dubbo组件的实践
  • Dapp开发-如何开发一个dapp
  • Vue 2 项目中配置 Tailwind CSS 和 Font Awesome 的最佳实践
  • MYSQL之表的约束
  • rbac模型详解
  • PHP编写图书信息爬虫程序
  • 力扣451:根据字符频率排序(桶排序)
  • 快解析为TPDDNS用户提供免费替换服务
  • 小白学习Java第18天(上):mybatis
  • 994. 腐烂的橘子
  • MYSQL时间函数、group by 和partition by的区别、组内编号leetcode学习
  • GitHub 趋势日报 (2025年05月11日)
  • LeetCode热题100——链表
  • docker-compose的yml文件配置deploy参数失效use the ‘deploy‘ key, which will be ignored.
  • MIMO 检测(2)--噪声白化
  • 雷池WAF的身份认证 - 钉钉配置教程
  • hi3516cv610的VPSS_ONLINE支持在vpss做图片放大的操作吗
  • IT团队如何通过ManageEngine卓豪Endpoint Central有效管理远程终端
  • 解决echartsV5+ restore后echarts显示空白