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); }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值