STL迭代器适配器

STL迭代器适配器

迭代适配器是借助5种基础迭代器(输入迭代器、输出迭代器、前向迭代器、双向迭代器、随机访问迭代器)实现的,并对成员方法进行了修改并添加了一些新的方法。

迭代器适配器

名称 功能
反向迭代器(reverse_iterator) 又称“逆向迭代器”,其内部重新定义了递增运算符(++)和递减运算符(--),专门用来实现对容器的逆序遍历。
安插型迭代器(inserter或者insert_iterator) 通常用于在容器的任何位置添加新的元素,需要注意的是,此类迭代器不能被运用到元素个数固定的容器(比如 array)上。
流迭代器(istream_iterator / ostream_iterator) 流缓冲区迭代器(istreambuf_iterator / ostreambuf_iterator) 输入流迭代器用于从文件或者键盘读取数据;相反,输出流迭代器用于将数据输出到文件或者屏幕上。 输入流缓冲区迭代器用于从输入缓冲区中逐个读取数据;输出流缓冲区迭代器用于将数据逐个写入输出流缓冲区。
移动迭代器(move_iterator) 此类型迭代器是 C++ 11 标准中新添加的,可以将某个范围的类对象移动到目标范围,而不需要通过拷贝去移动。

1.reverse_iterator

反向迭代器是通过基础迭代器实现的,rbegin指向容器的最后一个元素,rend指向第一个元素的前一个位置

函数 功能
operator* 以引用的形式返回当前迭代器指向的元素。
operator+ 返回一个反向迭代器,其指向距离当前指向的元素之后 n 个位置的元素。此操作要求基础迭代器为随机访问迭代器。
operator++ 重载前置 ++ 和后置 ++ 运算符。
operator+= 当前反向迭代器前进 n 个位置,此操作要求基础迭代器为随机访问迭代器。
operator- 返回一个反向迭代器,其指向距离当前指向的元素之前 n 个位置的元素。此操作要求基础迭代器为随机访问迭代器。
operator-- 重载前置 -- 和后置 -- 运算符。
operator-= 当前反向迭代器后退 n 个位置,此操作要求基础迭代器为随机访问迭代器。
operator-> 返回一个指针,其指向当前迭代器指向的元素。
operator[n] 访问和当前反向迭代器相距 n 个位置处的元素。
base() 返回当前反向迭代器底层所使用的基础迭代器

2.insert_iterator

迭代器适配器 功能
back_insert_iterator 在指定容器的尾部插入新元素,但前提必须是提供有 push_back() 成员方法的容器(包括 vector、deque 和 list)。
front_insert_iterator 在指定容器的头部插入新元素,但前提必须是提供有 push_front() 成员方法的容器(包括 list、deque 和 forward_list)。
insert_iterator 在容器的指定位置之前插入新元素,前提是该容器必须提供有 insert() 成员方法。

提供有 push_back() 成员方法的容器包括 vector、deque 和 list。

vector<int> res;
back_insert_iterator<Container> back_it (res);//只有这种定义方式
back_it=1;//在res末尾插入1
back_it=2;//在res末尾插入2
//每次将新元素插入到容器的末尾后,原本指向容器末尾的迭代器会后移一位,指向容器新的末尾。
template <class Container> back_insert_iterator<Container> back_inserter (Container& x);
//在容器的任意插入元素
insert_iterator<Container> insert_it (container,it);
insert_iterator<int> insert_it(res,res.begin()+2);

3.istream_iterator

输入流迭代器用于从输入流中读取数据,通过重载++运算符实现,运算符内调用>>读取数据,

//创建了一个可读取 double 类型元素,并代表结束标志的输入流迭代器
istream_iterator<double> eos;

STL迭代器适配器

迭代适配器是借助5种基础迭代器(输入迭代器、输出迭代器、前向迭代器、双向迭代器、随机访问迭代器)实现的,并对成员方法进行了修改并添加了一些新的方法。

迭代器适配器

名称 功能
反向迭代器(reverse_iterator) 又称“逆向迭代器”,其内部重新定义了递增运算符(++)和递减运算符(--),专门用来实现对容器的逆序遍历。
安插型迭代器(inserter或者insert_iterator) 通常用于在容器的任何位置添加新的元素,需要注意的是,此类迭代器不能被运用到元素个数固定的容器(比如 array)上。
流迭代器(istream_iterator / ostream_iterator) 流缓冲区迭代器(istreambuf_iterator / ostreambuf_iterator) 输入流迭代器用于从文件或者键盘读取数据;相反,输出流迭代器用于将数据输出到文件或者屏幕上。 输入流缓冲区迭代器用于从输入缓冲区中逐个读取数据;输出流缓冲区迭代器用于将数据逐个写入输出流缓冲区。
移动迭代器(move_iterator) 此类型迭代器是 C++ 11 标准中新添加的,可以将某个范围的类对象移动到目标范围,而不需要通过拷贝去移动。

1.reverse_iterator

反向迭代器是通过基础迭代器实现的,rbegin指向容器的最后一个元素,rend指向第一个元素的前一个位置

函数 功能
operator* 以引用的形式返回当前迭代器指向的元素。
operator+ 返回一个反向迭代器,其指向距离当前指向的元素之后 n 个位置的元素。此操作要求基础迭代器为随机访问迭代器。
operator++ 重载前置 ++ 和后置 ++ 运算符。
operator+= 当前反向迭代器前进 n 个位置,此操作要求基础迭代器为随机访问迭代器。
operator- 返回一个反向迭代器,其指向距离当前指向的元素之前 n 个位置的元素。此操作要求基础迭代器为随机访问迭代器。
operator-- 重载前置 -- 和后置 -- 运算符。
operator-= 当前反向迭代器后退 n 个位置,此操作要求基础迭代器为随机访问迭代器。
operator-> 返回一个指针,其指向当前迭代器指向的元素。
operator[n] 访问和当前反向迭代器相距 n 个位置处的元素。
base() 返回当前反向迭代器底层所使用的基础迭代器

2.insert_iterator

迭代器适配器 功能
back_insert_iterator 在指定容器的尾部插入新元素,但前提必须是提供有 push_back() 成员方法的容器(包括 vector、deque 和 list)。
front_insert_iterator 在指定容器的头部插入新元素,但前提必须是提供有 push_front() 成员方法的容器(包括 list、deque 和 forward_list)。
insert_iterator 在容器的指定位置之前插入新元素,前提是该容器必须提供有 insert() 成员方法。

提供有 push_back() 成员方法的容器包括 vector、deque 和 list。

vector<int> res;
back_insert_iterator<Container> back_it (res);//只有这种定义方式
back_it=1;//在res末尾插入1
back_it=2;//在res末尾插入2
//每次将新元素插入到容器的末尾后,原本指向容器末尾的迭代器会后移一位,指向容器新的末尾。
template <class Container> back_insert_iterator<Container> back_inserter (Container& x);
//在容器的任意插入元素
insert_iterator<Container> insert_it (container,it);
insert_iterator<int> insert_it(res,res.begin()+2);

3.istream_iterator

输入流迭代器用于从输入流中读取数据,通过重载++运算符实现,运算符内调用>>读取数据,

//创建了一个可读取 double 类型元素,并代表*结束标志*的输入流迭代器
istream_iterator<double> eos;
//创建读取输入流的迭代器
istream_iterator<double> iit(std::cin);
double value1,value2;
if (iit != eos) {
    //读取一个元素,并赋值给 value1
    value1 = *iit;
}
iit++;
if (iit != eos) {
    //读取第二个元素,赋值给 value2
    value2 = *iit;
}

4.ostream_iterator

通过重载=实现,每个输出的元素会放到输出流里

//创建指定输出流的迭代器
ostream_iterator<int> out_it(std::cout);
//写入元素之间插入分隔符
ostream_iterator<int> out_it(std::cout,",");
ostream_iterator<int> out_it1(out_it);//拷贝构造
*out_it = "first";//直接输出该元素
cout<<endl;//输出回车
vector<int> res;
copy(res.begin(),res.end(),out_it);//将res中的元素写入到输出流

5.streambuf_iterator

从输入缓冲区中读取字符,与istream_iterator相比,只能读取字符,不涉及类型转换,速度快

//表示结尾的缓冲区迭代器
istreambuf_iterator<char> end_in;
//指定读取的缓冲区
istreambuf_iterator<char> in{cin};
//指定读取的缓冲区地址
istreambuf_iterator<char> in{cin.rdbuf()};
while(in!=end_in){
    str+=*in++;
}

6.ostreambuf_iterator

将指定字符写入到输出缓冲区

//传递缓冲区对象
ostreambuf_iterator<char> out_it(cout);
//传递缓冲区对象地址
ostreambuf_iterator<char> out_it(cout.rdbuf());
*out_it='A';
string s="STL";
copy(s.begin(),s.end(),out_it);

7.move_iterator

通过移动而不是复制的方式将元素移动

//通过调用该模板类的默认构造函数,可以创建一个不指向任何对象的移动迭代器。
//将 vector 容器的随机访问迭代器作为新建移动迭代器底层使用的基础迭代器
typedef vector<string>::iterator Iter;
//调用默认构造函数,创建移动迭代器
move_iterator<Iter>mIter;

//创建move_iterator同时初始化
vector<string> myvec{ "one","two","three" };
typedef vector<string>::iterator Iter;
std::move_iterator<Iter>mIter(myvec.begin());//指向第一个元素

//move_iterator支持用已有的同类型的move_iterator初始化
move_iterator<Iter>mIter2(mIter);

//调用make_move_iterator
template <class Iterator> move_iterator<Iterator> make_move_iterator (const Iterator& it);
typedef vector<string>::iterator Iter;
vector<string> myvec{ "one","two","three" };
move_iterator<Iter>mIter = make_move_iterator(myvec.begin());
vector<string> v{ "one","two","three" };
vector<string> it(make_move_iterator(v.begin()), make_move_iterator(v.end()));
//移动后v中没有元素

move_iterator 模板类提供base()方法,获取到移动迭代器底层所使用的基础迭代器

8.advance、distance

迭代器辅助函数 功能
advance(it, n) it 表示某个迭代器,n 为整数。该函数的功能是将 it 迭代器前进或后退 n 个位置。n可以为负(后退)
distance(first, last) first 和 last 都是迭代器,该函数的功能是计算 first 和 last 之间的距离。
begin(cont) cont 表示某个容器,该函数可以返回一个指向 cont 容器中第一个元素的迭代器。
end(cont) cont 表示某个容器,该函数可以返回一个指向 cont 容器中最后一个元素之后位置的迭代器。
prev(it) it 为指定的迭代器,该函数默认可以返回一个指向上一个位置处的迭代器。注意,it 至少为双向迭代器。
next(it) it 为指定的迭代器,该函数默认可以返回一个指向下一个位置处的迭代器。注意,it 最少为前向迭代器。
vector<int> arr{1,2,3};
vector<int>::iterator it=arr.begin();
advance(it,2);//3
distance(it.begin(),it.end());//3

9.const_iterator

vector.insert(iterator,value);

这里iterator的类型为const_iterator(const_reverse_iterator),当传入iterator(reverse_iterator)时会进行隐式类型转换

强制转换

//将 const_iterator 转换为 iterator
advance(iter, distance<cont<T>::const_iterator>(iter,citer));
//将 const_reverse_iterator 转换为 reverse_iterator
advance(iter, distance<cont<T>::const_reverse_iterator>(iter,citer));

实现方式的本质是,先创建一个迭代器 citer,并将其初始化为指向容器中第一个元素的位置。在此基础上,通过计算和目标迭代器 iter 的距离(调用 distance()),将其移动至和 iter 同一个位置(调用 advance()),由此就可以间接得到一个指向同一位置的 iter 迭代器。

10.begin()、end()

template <class Container> auto begin (Container& cont);//返回普通迭代器
template <class Container> auto begin (const Container& cont);//返回const类型迭代器

begin(vector) 等同于执行 vector.begin()

begin(),end()也可以用来遍历数组

int arr[]=[1,2,3,4,5];
for (int *it = begin(arr); it != end(arr); ++it)
    cout<<*it<<endl;

11.prev()、next()

advance移动的是迭代器本身

prev() 获取一个距离指定迭代器 n 个元素的迭代器

vector<int> arr{1,2,3,4,5};
auto it=arr.end();
auto i=prev(it,2);//2,返回一个新的迭代器
上一篇:十一、生成器和迭代器 4.生成器与yield关键字


下一篇:总结 -集合