1 講一個容器初始化爲另一個容器的副本
前提是類型的匹配:容器類型和元素類型都必須相同。
2 初始化爲一段元素的副本
儘管不能用一種容器內的元素複製給另一種容器,但系統允許通過傳遞一對迭代器間接實現功能。使用迭代器時,不要求容器類型相同,容器內的元素類型也可以不相同,只要他們相互兼容。
vector<string> svec;
//initialize slist with copy of each element ofsvec
list<string> slist(svec.begin(),svec.end());
//find midpoint in the svec
vector<string>::iterator mid=svec.begin()+svec.size()/2;
//initialize front with first half of svec:The elememts up to but not including *mid
deque<string> front(svec.begin(),mid);
//initialize front with second half of svec:The elememts *mid through end of svec
deque<string> back(mid,svec.end());
其實指針也是一種迭代器。
char *words[]={"stately","plump","buck","mulligan"};
size_t words_size=sizeof(words)/sizeof(char*);
list<string> word2(words,words+words_size);
3 分配和初始化指定數目的元素
創建順序容器時,可現實的制定容器大小和一個(可選的)元素初始化式。容器大小可以是常量或者非常量表達式。
const list<int>::size_type list_size=64;
list<string> slist(list_size,"xiaoyu");//64 strings,each is xiaoyu
list<int> ilist(list_size);//64 elements, each initialized to 0
注意:接受容器大小做形參的構造函數只是用與順序容器,而關聯容器不支持這種初始化。 int ai[6]={1,2,3,4,5,6};
string sa[6]={"1","2","3","4","5","6"};
vector<string> svec(sa,sa+6);
list<string> slist(sa+6,sa);//error 順序出錯
解釋複製容器對象的構造函數和使用兩個迭代器的構造函數之間的差別答: 差別在於複製容器對象的構造函數只能將一個容器初始化爲另一個容器的副本,即複製一個容器內的全部元素,這種構造函數要求兩容器是同類型的,元素也是相同類型的;使用兩個迭代器的夠凹函數可以將一個容器初始化爲另一個容器的子序列,而且採用這種構造函數不要求兩個容器是同類型的,其元素只要能相互兼容就可以。
4 容器內元素的類型約束
容器元素類型必須滿足兩方面:
1 元素類型必須支持賦值運算。
2 元素類型的對象必須可以複製。
注意:引用不支持一般意義的賦值運算,因此沒有元素是引用類型的容器。除了輸入輸出標準庫類型(IO庫類型不支持賦值或複製,因此不可以創建存放IO類型對象的容器)和auto_ptr類型外,所有其他的標準庫類型都是有效的容器元素類型。
例如類Foo沒有默認的構造函數,但提供了需要一個int型參數的構造函數。
vector<Foo> empty;
vector<Foo> bad(10);
vector<Foo> Ok(10,1);
iter1-iter2;>,>=,<,<=只適用於vector和deque類型的迭代器。
關係操作符只適用於vector和deque容器。這是因爲只有這兩種容器爲其元素提供快速、隨機的訪問。他們確保可根據元素位置直接用小的訪問指定的容器元素。這兩種容器都支持通過元素位置實現的隨機訪問,因此它們的迭代器可以有效的實現算術和關係運算。
例如: vector<int>::iterator iter=vec,begin()+vec.size()/2;
另外: list<int> ilist(vec.begin(),iter);
ilist.begin()+ilist.size()/2;//error:no addition on list iterator.因爲list迭代器不支持算術運算,也不支持關係運算,它只提供潛質和後置的自增、自減運算以及相等或者不等運算。
5 容器元素都是副本:
在容器添加元素時,系統是將元素值複製到容器裏。
list<string> lst;
list<string>::iterator iter=lst.begin();
string word;
while(cin>>word)
iter=lst.insert(iter,word);
上述代碼等效於調用push_front函數。下標訪問的叫隨機訪問容器 只有vector string等 a[1].... list不能通過下標訪問 只能通過iterator一個個訪問resize操作可能會使迭代器失效。在vector或deque容器上做resize操作有可能使所有的迭代器都失效。
使用只帶有一個長度參數的resize操作對於元素類型來說有什麼要求?
答: 因爲只帶有一個長度參數的resize操作對新添加的元素進行值初始化,所以元素類型如果是類類型,則該類必須顯示提供默認構造函數,或者該類不顯示提供任何構造函數以便使用編譯器自動合成的默認構造函數。(待續...)