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,返回一个新的迭代器