ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

STL迭代器适配器

2021-10-25 14:04:21  阅读:180  来源: 互联网

标签:容器 迭代 iterator insert 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,返回一个新的迭代器

标签:容器,迭代,iterator,insert,STL,适配器,元素,指向
来源: https://www.cnblogs.com/iven98/p/15458210.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有