1. 程式人生 > 其它 >迭代器和反向迭代器,常量迭代器和非常量迭代器

迭代器和反向迭代器,常量迭代器和非常量迭代器

技術標籤:c++C++STL

迭代器的型別共有4種:<T>::Iiterator,<T>::const_iterator,<T>::reverse_iterator,<T>::const_reverse_iterator

#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
string line = "you,are,robert";
//返回結果是常量反向迭代器,所以這裡必須定義一個常量反向迭代器
string::const_reverse_iterator it = find(line.crbegin(),line.crend(),',');
cout << *it << endl;
//line.crbegin()必須在it的前面,這兩個迭代器必須保持字面的先後順序
//(rbegin就在最前面,rend最後)
string  word(line.crbegin(),it);
//string new_word(word.rbegin(),word.rend());
//sort(word.begin(),word.end());
//sort(word.rbegin(),word.rend());
cout << "cout the word:" << endl;
cout << word << endl;
for(auto i = word.rbegin();i != word.rend();++i)
	cout  << *i;

return 0;
}
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
string line = "you,are,robert";
//返回的是常量的反向迭代器,這裡也必須定義相同的型別
string::const_reverse_iterator it = find(line.crbegin(),line.crend(),',');
cout << *it << endl;
//下面的兩個迭代器必須型別完全一致(常量特性,是否反向迭代器,crbegin()必須在最前面)
string  word(line.crbegin(),it);
//這裡it.base()已經是一個普通的常量迭代器,注意it.base()得到的和it的常量特性是相同的
//所以line.cend()也是一個常量迭代器
string  new_word(it.base(),line.cend());
cout << new_word << endl;
  return 0;
}

注意:自己總結出如下規則(不足之處批評指正)

(1)reverse_iterator有base()成員函式,可以返回它的普通迭代器.

(2)反向迭代器轉換為普通迭代器時候,不改變const特性,例如:string::const_reverse_iterator it it.base()也是一個常量迭代器,因為轉換不改變常量特性

(3)在初始化其餘容器型別時候,begin()必須在end()之前(如果有中間元素迭代器也一樣),rbegin()必須在rend()之前(如果有中間元素的迭代器也一樣)。即迭代器或者反向迭代器必須遵循理論上字面順序。

(4)用一對迭代器初始化別的容器型別物件的時候,常量特性必須保持一致,是否是反向迭代器也必須一致(儘管通常不用反向迭代器初始化一個string物件,因為會把每個字母倒過來解讀)。

例如 vector<int> elem(it1,it2);it1和it2如果一個是常量迭代器,另一個也必須是(或者都不是常量迭代器)。

而且it1和it2要麼都是反向迭代器,要麼都不是反向迭代器。

(5)如果是兩個迭代器比較的時候,只要只想同一個元素,如果僅僅只有const的差別,那麼結果是相等的。

(6)反向迭代器和普通迭代器呼叫演算法的時候:

把普通迭代器初始化反向迭代器,最後得到一組反向迭代器範圍,那麼處理的範圍是一樣的,例如:


#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <forward_list>
#include <stack>
#include <vector>
#include <forward_list>
#include <deque>
#include <array>
#include <list>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
//這裡假設要反向列印vector中第二個到第七個元素:
	
vector<int> vint{1,2,3,4,5,6,7,8,9,0};

ostream_iterator<int> out_iter(cout);

//那麼根據迭代器的左閉右開準則,給的範圍是3-8個,
//接下來把迭代器的3-8個元素轉變為反向迭代器it3和it4,
//(it4,it3)這個處理範圍對應3-8個範圍
//一句話:把一對普通迭代器轉換成反向迭代器,處理的範圍和原來迭代器範圍一樣
//執行結果是:76543
vector<int>::reverse_iterator it3(vint.begin() + 2),it4(vint.begin() + 7);
copy(it4,it3,out_iter);

//反過來,把一對反向迭代器轉化成普通迭代器後,處理範圍會改變嗎?
vector<int>::iterator i1 = it3.base(),i2 = it4.base();
copy(i1,i2,out_iter);
//執行結果是 34567



return 0;
}

(7)c++ primer(5th)365頁上說,從普通迭代器給反向迭代器賦值或者初始化,那麼得到的不是指向同一個元素的迭代器,但是我在gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04) 上,不能用普通迭代器給反向迭代器賦值(這裡指等號賦值)。

這裡必須採用圓括號初始化才可以。賦值本人還不會,有大神會就給我回復一個,謝謝!!!

而反向迭代器給普通迭代器賦值,必須通過反向迭代器的成員函式base()才能實現