文章目錄
前言
首先我們知道在容器中,迭代器分爲:
- iterator
- const_iterator
- reverse_iterator
- const_reverse_iterator
官方文檔對迭代器實際上可以分爲這幾類:
- Input iterator 輸入迭代器
- Output iterator 輸出迭代器
- Forward iterator 正向迭代器
- Bidirectional iterator 雙向迭代器
- Random-access iterator 隨機存取迭代器
注意每個容器的迭代器類型不一定相同,如vector的迭代器就是隨機存取迭代器,而list則是雙向迭代器
具體的可以在www.cplusplus.com/reference/iterator/index.html
進行查閱
一.Functions(函數)操作
- advance
- distance
- prev
- next
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; });
}
二.Iterator generators
- back_inserter:不斷往後插入元素
- front_inserter:不斷往前插入元素
- inserter:需要確定容器與插入的位置
這些操作可以用來針對哪些沒有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;
}
三.predefined iterator
1.insert_iterator、back_insert_iterator、front_insert_iterator
- insert_iterator:容器中必須有insert操作
- back_insert_iterator:容器中必須有push_back操作
- front_insert_iterator:容器中必須有push_front操作
y67
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<vector<int>> front_it(newvec);
std::copy(vec.begin(), vec.end(), front_it);
for (auto& e: newvec)
cout << e << endl;
*/
}
2.reverse_iterator
這裏需要特別注意的是: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;
}
3.istream_iterator ostream_iterator
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);
}
4.std::move 與 std::move_iterator
移動語義 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;
}