首先我们知道在容器中,迭代器分为:
官方文档对迭代器实际上可以分为这几类:
注意每个容器的迭代器类型不一定相同,如vector的迭代器就是随机存取迭代器,而list则是双向迭代器
具体的可以在www.cplusplus.com/reference/iterator/index.html
进行查阅
void test1()
{
//advance
list<int> mylist{1, 2, 3, 4, 5, 6};
list<int>::iterator it = mylist.begin();
//it +=5;//ERROR!iterator do not support operator +=
it++;
it++;
it++;
it++;
cout << *it << endl;
it = mylist.begin();
advance(it, 2);
cout << *it << endl;
//distance
cout << "distance:" << distance(mylist.begin(), it) << endl;
//prev
it = mylist.end();
cout << "The last element:" << *(--it) << endl;
cout << "Now *it = " << *it << endl;
cout << "如果并不想要迭代器变化,只想输出迭代器指向前一个元素的迭代器:" << endl;
cout << *prev(mylist.end()) << endl;
//next
cout << *next(mylist.begin()) << endl;
cout << "next还可以有类似advance的用法,但是也并不会改变原来的迭代器指向" << endl;
cout << *next(mylist.begin(), 3) << endl;
cout << "for_each + next" << endl;
for_each(mylist.begin(), next(mylist.begin(), 3), [](int x) { cout << x << endl; });
}
这些操作可以用来针对哪些没有insert函数的容器使用
//例题:要在一个容器中间插入另外一个容器的元素
void test2()
{
list<int> mylist{1, 2, 3, 4, 5};
list<int> newlist{10, 20, 30, 40};
auto it = newlist.begin();
std::advance(it, 2);
std::copy(mylist.begin(), mylist.end(), inserter(newlist, it));
for (auto &e : newlist)
cout << e << endl;
}
//back_inserter front_inserter
void test3()
{
list<int> mylist{1, 2, 3, 4, 5};
list<int> newlist;
//不要用.end()来执行copy操作,因为.end()返回的并不属于插入迭代器,并不能对newlist进行扩容,所以会发生错误
// std::copy(mylist.begin(), mylist.end(), newlist.end());
//back_inserter
std::copy(mylist.begin(), mylist.end(), std::back_inserter(newlist));
for (auto &e : newlist)
cout << e << endl;
cout << "-----------------------------" << endl;
//front_inserter 注意这里插入的顺序是相反的
list<int> mylist2{6, 7, 8, 9};
std::copy(mylist.begin(), mylist.end(), std::front_inserter(mylist2));
for (auto &e : mylist2)
cout << e << endl;
}
void test4()
{
list<int> mylist{1, 2, 3, 4, 5};
list<int> newlist;
//insert_iterator
std::insert_iterator<list<int>> insert_it(newlist, newlist.begin());
std::copy(mylist.begin(), mylist.end(), insert_it);
for (auto &e : newlist)
cout << e << endl;
cout << "--------------------------" << endl;
vector<int> vec{1, 2, 3};
vector<int> newvec{10, 20, 30};
std::back_insert_iterator<vector<int>> back_it(newvec);
std::copy(vec.begin(), vec.end(), back_it); //如果换成vec.end()会报错
for (auto &e : newvec)
cout << e << endl;
cout << "----------------------------------" << endl;
/*
//ERROR!vector中没有push_front操作
std::front_insert_iterator> front_it(newvec);
std::copy(vec.begin(), vec.end(), front_it);
for (auto& e: newvec)
cout << e << endl;
*/
}
这里需要特别注意的是:reverse_iterator 相比 iterator 会向左边有1个单位的offset(偏移)
因为STL容器中的函数,如erase, insert函数等等只能操作正向迭代器,不能操作反向迭代器,所以反向迭代器中便有了base函数将其转换为正向迭代器,但是注意有偏移
注意:使用base函数之后,指针右移一位,再转换为正向迭代器
/*
? 1 2 3 4 5 ?
vec.begin() vec.end()
rbeg
rend
*/
void test5()
{
vector<int> vec{1, 2, 3, 4, 5};
std::reverse_iterator<vector<int>::iterator> rbeg(vec.end());
std::reverse_iterator<vector<int>::iterator> rend(vec.begin());
cout << *rbeg << endl;
cout << *rbeg.base() << endl;
cout << *rend << endl;
cout << *rend.base() << endl;
cout << "-------用逆向迭代器删除数组中的3------------" << endl;
std::reverse_iterator<vector<int>::iterator> rit = find(vec.rbegin(), vec.rend(), 3);
std::reverse_iterator<vector<int>::iterator> rit2 = rit;
cout << *rit << endl;
rit++;
cout << *rit << endl;
rit++;
cout << *rit << endl;
cout << "由此可见rit 的本质仍然是反向迭代器" << endl;
// vec.erase(rit2);
// vec.erase(rit2.base());
vec.erase((++rit2).base());
cout << "----------------print---------------------------" << endl;
for (auto &e : vec)
cout << e << endl;
}
void test6()
{
vector<int> vec{1, 2, 3, 4, 5};
std::reverse_iterator<vector<int>::iterator> rbeg(vec.end());
std::reverse_iterator<vector<int>::iterator> rend(vec.begin());
cout << "迭代器的类型-----------------------------" << endl;
vector<int>::reverse_iterator rit = rbeg;
std::reverse_iterator<vector<int>::iterator> rit2 = rbeg;
cout << *rit << endl;
cout << *rit2 << endl;
cout << "正序打印---------------------------------" << endl;
for (vector<int>::iterator it = rend.base(); it != rbeg.base(); it++)
cout << *it << endl;
cout << "逆序打印---------------------------------" << endl;
while (rbeg != rend)
cout << *rbeg++ << endl;
}
cin输入的次数取决于istream_it迭代器的移动次数
ostream_it会自动输出移动
void test7()
{
std::istream_iterator<double> istream_it(std::cin);
std::istream_iterator<double> eof;
vector<double> vec;
vec.push_back(*istream_it);
istream_it++;
vec.push_back(*istream_it);
istream_it++;
vec.push_back(*istream_it);
istream_it++;
for (auto &e : vec)
cout << e << endl;
}
void test8(){
vector<int> vec{1,2,3,4,5};
std::ostream_iterator<int> ostream_it(cout," ");
*ostream_it = 1;
*ostream_it = 2;
*ostream_it = 3;
cout << endl;
cout << "----------------------------" << endl;
std::copy(vec.begin(), vec.end(), ostream_it);
}
移动语义 move 与 移动迭代器
注意:当src元素中move过去之后就不能再使用了,尽管还能够再次输出,但是程序有安全隐患。
void test9(){
vector<int> src{1,2,3,4};
vector<int> dest{5,6,7};
typedef vector<int>::iterator Iter;//定义底层的基本迭代器
std::copy(std::move_iterator<Iter>(src.begin()), std::move_iterator<Iter>(src.end()), std::back_inserter(dest));
// std::move(src.begin(), src.end(), std::back_inserter(dest));
cout << "src:" << endl;
for (auto& e: src)
cout << e << " ";
cout << endl;
cout << "dest:" << endl;
for (auto& e: dest)
cout << e << " ";
cout << endl;
}