欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 高考 > C++标准模板(STL)- 迭代器库 - 流迭代器- 从 std::basic_streambuf 读取的输入迭代器(二)

C++标准模板(STL)- 迭代器库 - 流迭代器- 从 std::basic_streambuf 读取的输入迭代器(二)

2026/3/9 23:13:11 来源:https://blog.csdn.net/qq_40788199/article/details/140085425  浏览:    关键词:C++标准模板(STL)- 迭代器库 - 流迭代器- 从 std::basic_streambuf 读取的输入迭代器(二)

迭代器库-流迭代器


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

迭代器分类

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

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

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

从 std::basic_streambuf 读取的输入迭代器

std::istreambuf_iterator
template< class CharT, class Traits = std::char_traits<CharT> >

class istreambuf_iterator : public std::iterator< std::input_iterator_tag,
                                                  CharT,
                                                  typename Traits::off_type,
                                                  /* unspecified, usually CharT* */,

                                                  CharT >
(C++17 前)

template< class CharT, class Traits = std::char_traits<CharT> >
class istreambuf_iterator;

(C++17 起)

std::istreambuf_iterator 是单趟迭代器,从为之构造迭代器的 std::basic_streambuf 对象读取相继字符。

默认构造的 std::istreambuf_iterator 迭代器被称为流尾迭代器。合法的 std::istreambuf_iterator 抵达底层流结尾时,它变得等于流尾迭代器。解引用或进一步自增它导致未定义行为。

std::istreambuf_iterator 拥有平凡复制构造函数、 constexpr 默认构造函数和平凡析构函数。

成员类型

成员类型定义
iterator_categorystd::input_iterator_tag
value_typeCharT
difference_typeTraits::off_type
pointer/* unspecified, usually CharT* */
referenceCharT
char_typeCharT
traits_typeTraits
int_typetypename traits::int_type
streambuf_typestd::basic_streambuf<CharT, Traits>
istream_typestd::basic_istream<CharT, Traits>
/* proxy */实现定义的类类型。名称 proxy 仅为说明。
proxy 对象保有一个 char_type 字符和一个 streambuf_type* 指针。
operator* 解引用 proxy 对象得到存储的字符。

 

获得当前字符的副本 若 CharT 拥有成员,则访问当前字符的成员

std::istreambuf_iterator<CharT,Traits>::operator*, operator->

CharT operator*() const;

(1)

pointer operator->() const;

(2)(C++11 起)
(C++17 前)

以调用 sbuf_->sgetc() 读取单个字符,其中 sbuf_ 是存储的指向流缓冲的指针。

若迭代器是流尾迭代器则行为未定义。

参数

(无)

返回值

1) 获得字符的值。

2) 未指定类型对象,满足给定一个 istreambuf_iterator i ,表达式 (*i).m 与 i->m 拥有相同效果。

异常

(无)

推进迭代器

std::istreambuf_iterator<CharT,Traits>::operator++, operator++(int)

istreambuf_iterator& operator++();

(1)

/* proxy */ operator++(int);

(2)

以调用 sbuf_->sbumpc() 推进迭代器,其中 sbuf_ 是存储的指向流缓冲的指针。

若迭代器是流尾迭代器则行为未定义。

参数

(无)

返回值

1) *this 。

2) 保有经由 operator*() 获得的当前字符和 sbuf_ 指针的 proxy 对象。以 operator* 解引用 proxy 对象得到存储的字符。

名称 proxy 仅为说明。

异常

(无)

调用示例

#include <iostream>
#include <sstream>
#include <iterator>
#include <numeric>
#include <algorithm>
#include <vector>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());
}std::ostringstream &operator<<(std::ostringstream &os, const Cell &cell)
{os << "{" << std::to_string(cell.x) << "," << std::to_string(cell.y) << "}";return os;
}std::istringstream &operator>>(std::istringstream &is, Cell &cell)
{is >> cell.x;is >> cell.y;return is;
}int main()
{// 典型使用:输入流以一对迭代器表示std::istringstream istringstream1("Hello, world");std::vector<char> vector1((std::istreambuf_iterator<char>(istringstream1)),std::istreambuf_iterator<char>());std::cout << "vector1 has " << vector1.size() << " bytes. ";vector1.push_back('\0');std::cout << "it holds \"" << &vector1[0] << std::endl;// 单趟生态的演示std::istringstream istringstream2("abcdefg");std::istreambuf_iterator<char>istreambuf_iterator1(istringstream2), istreambuf_iterator2(istringstream2);std::cout << "istreambuf_iterator1 returns " << *istreambuf_iterator1 << std::endl;std::cout << "istreambuf_iterator2 returns " << *istreambuf_iterator2 << std::endl;++istreambuf_iterator1;std::cout << "after incrementing istreambuf_iterator1, but not istreambuf_iterator2" << std::endl;std::cout << "istreambuf_iterator1 returns " << *istreambuf_iterator1 << std::endl;std::cout << "istreambuf_iterator2 returns " << *istreambuf_iterator2 << std::endl;++istreambuf_iterator2; // 这使得 *i2 的表观值从 'a' 跳到 'c'std::cout << "after incrementing istreambuf_iterator2, but not istreambuf_iterator1" << std::endl;std::cout << "istreambuf_iterator1 returns " << *istreambuf_iterator1 << std::endl;std::cout << "istreambuf_iterator2 returns " << *istreambuf_iterator2 << std::endl;alg(istreambuf_iterator1, istreambuf_iterator1);return 0;
}

输出

vector1 has 12 bytes. it holds "Hello, world
istreambuf_iterator1 returns a
istreambuf_iterator2 returns a
after incrementing istreambuf_iterator1, but not istreambuf_iterator2
istreambuf_iterator1 returns b
istreambuf_iterator2 returns a
after incrementing istreambuf_iterator2, but not istreambuf_iterator1
istreambuf_iterator1 returns b
istreambuf_iterator2 returns c
alg() called for input iterator

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词