国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
[譯]2010新版STL修訂內(nèi)容(VC2010) | ColinOrg
揭示STL重要更改
預(yù)備知識(shí):
l 理解標(biāo)準(zhǔn)C++ 0x 的concepts,例如:auto 關(guān)鍵字,lambda 表達(dá)式、右值引用等。
l 熟練使用STL。熟悉2個(gè)及以上STL容器的使用。
l 你手上必須有有VC2010的編譯器,或者其它支持最新的C++標(biāo)準(zhǔn)和更新Stl的編譯器。
這篇文章介紹了新版STL修訂內(nèi)容。這些變化是TR1中最為關(guān)注的內(nèi)容(譯注1);以下是STL的新增特性:
l Constant迭代器
l array類(lèi)
l tuple類(lèi)
l <algorithm>中新增函數(shù)
l 隨機(jī)生成器類(lèi)(<random>)
l 對(duì)sets及無(wú)序sets容器的改進(jìn)
l 對(duì)maps及無(wú)序maps的改進(jìn)
l 正則表達(dá)式
l 功能的改進(jìn)及實(shí)用的頭文件
l 加強(qiáng)指針管理類(lèi)
Constant 迭代器
首先說(shuō)明,constant迭代器并不等于const迭代器。constant迭代器是const_iterator。 將const關(guān)鍵字加在 iterator前時(shí),其所指的變量是無(wú)法修改的。而const_iterator則在首次賦值后不再可指向其它變量(類(lèi)似:常量指針和指向常量的指針)看了下面代碼后,你應(yīng)該會(huì)有一個(gè)清晰的認(rèn)識(shí):
using namespace std;vector<int> IntVector;...// Normal iteratorvector<int>::iterator iter_nc = IntVector.begin();*iter_nc = 100; // Validiter_nc = IntVector.end(); // Valid// Constant Iteratorvector<int>::const_iterator iter_c = IntVector.begin();*iter_c = 100; // INVALID!iter_c = IntVector.end(); // Valid// The 'const' iteratorconst vector<int>::iterator iter_const = IntVector.begin();*iter_const = 100; // Validiter_const = IntVector.end(); // Invalid (Why? Learn C++!)// The 'const' Constant Iteratorconst vector<int>::const_iterator iter_const_c = IntVector.begin();*iter_const_c = 100; // Invalid!iter_const_c = IntVector.end(); // Invalid
新特性
容器中新增函數(shù)可以明確返回Constant迭代器。在此之前,我們先了解一下迭代器返回規(guī)則:
1. 如果容器是constant,或者類(lèi)方法前申明const,則將返回const_iterator。
2. 如果左值是const_iterator,普通的iterator將被返回,但會(huì)向下轉(zhuǎn)型為const_iterator;
3. 其它情況,將返回普通iterator;
注:大多數(shù)迭代器訪問(wèn)方法(eg:begin,end)有相應(yīng)的重載版本以返回constant 或non-const迭代器 ;
因此,你可明確指明返回的是constant還是普通迭代器;
以下為新增方法:
訪問(wèn)方法
含義
cbegin
返回容器第一個(gè)元素的const_iterator .
cend
返回容器最后一個(gè)元素后一位的 const_iterator .
crbegin
返回rbegin 的 const_iterator 。即最后一個(gè)元素的constant迭代器.
crend
返回rend的 const_iterator 。即第一個(gè)元素前一位的constant迭代器.
以上所有方法都在相應(yīng)的容器類(lèi)中申明為const。
為什么要引入這些方法?
你當(dāng)然可以指定你需要那種迭代器,可能你根本就不需要這些新的方法;
加入這些方法的主要原因是因?yàn)樾滦抻喌腶uto關(guān)鍵詞的引入;如果你已經(jīng)了解auto關(guān)鍵詞的含義,你應(yīng)該知道我們可以在變量申明時(shí)不用明確指定類(lèi)型。編譯器會(huì)根據(jù)表達(dá)式的右值推導(dǎo)變量類(lèi)型;當(dāng)有如下調(diào)用:
auto iter = IntVector.begin();
可以指定是普通還是constant迭代器被返回。因此,為了返回一個(gè)constant迭代器(const_iterator),你可以使用:
auto iter = IntVector.cbegin(); // cbegin// The return type is: vector<int>::const_iterator
這樣,這個(gè)迭代器以只讀模式遍歷vector,可以寫(xiě)出如下代碼:
for(auto iter = IntVector.cbegin(); iter != IntVector.cend(); ++iter) { }
需要說(shuō)明的是,constant迭代器可以訪問(wèn) 非const成員方法(我不敢保證,我只是在源碼中看到)。因此,最好使用cend來(lái)代替end檢查有效性。
在sets和maps集合中又是如何?
對(duì)于所有的集合類(lèi)(set,multiset, unordered_set, and unordered_multiset),其迭代器總是constant的。也就是說(shuō),當(dāng)調(diào)用方法begin/end,find 以及下標(biāo)操作符[],都是返回的constant 迭代器。像begin,find這些方法,雖然它們返回的數(shù)據(jù)類(lèi)型都是非constant迭代器,但其行為是constant迭代器。
看以下代碼:
set<int> is;is.insert(10);*is.begin() = 120;wcout << is.count(10) << ", " << is.count(120);
以上例子首先插入10到set中,然后試圖修改第一個(gè)元素的值。
因?yàn)橹挥幸粋€(gè)元素插入進(jìn)來(lái),begin將返回指向該元素的迭代器;在vc9及之前的編譯器中,可成功修改值為120;
但從vc10開(kāi)始,第三行將不能編譯通過(guò),編譯器報(bào)錯(cuò)為:
error C3892: ’std::**::begin’ : you cannot assign to a variable that is const
對(duì)于map,鍵不可修改,值可修改。以下是代碼示例:
map<int, int> imap;imap.insert( make_pair( 1, 1028 ));imap.insert( make_pair( 2, 2048 ));imap.find(1)->second = 1024; // Compilesimap.find(2)->first = 4; // Errorimap[2] = 2000;*imap.begin()->first = 10; // Error*imap.begin()->second= 10; // Compiles*imap.cbegin()->second= 10;// Error on VC10, since iterator is constant. NA for VC9
數(shù)組類(lèi)array
array類(lèi)是STL新增容器類(lèi),用于在存儲(chǔ)一個(gè)固定大小的數(shù)組。數(shù)組大小與數(shù)據(jù)元素類(lèi)型一同由模版參數(shù)指出。其指定的大小數(shù)值必須是一個(gè)常量運(yùn)行時(shí)的(與其它C/c++數(shù)組一樣)。不像其它容器能夠增加或減少容器大小,array支持其它標(biāo)準(zhǔn)方法-如迭代,隨機(jī)訪問(wèn),交換數(shù)據(jù),賦值等。
頭文件:<array>
命名空間:tr1.但由于’using tr1::array’ 已被頭文件包含。所有,在使用中,申明std就可以了。
示例:
array<int, 64> IntArray;
第一個(gè)參數(shù)指定模版數(shù)據(jù)類(lèi)型,第二個(gè)是一個(gè)常量編譯時(shí)的整型。定義之后,IntArray的大小不能再改變。當(dāng)然,除了int,可以使用其它的基本數(shù)據(jù)類(lèi)型。如果要使用自定義類(lèi),則要實(shí)現(xiàn)復(fù)制構(gòu)造函數(shù),重載賦值操作符,比較操作符。同時(shí),默認(rèn)構(gòu)造函數(shù)必須為公有。
這個(gè)類(lèi)的引入是為了和其它STL容器進(jìn)行無(wú)縫整合。例如,你使用vector或list,需要調(diào)用begin/end方法來(lái)訪問(wèn)元素。當(dāng)你想將其作為普通數(shù)組使用時(shí),代碼會(huì)編譯失敗。這必須改變。用array類(lèi),你可以同時(shí)獲得STL的靈活性和普通數(shù)據(jù)的性能。
依據(jù)最近的編譯器報(bào)告(tr1 增刊),可以使用以下方式來(lái)初始化array:
array<int, 64> IntArray;
如果忽略1個(gè)或多個(gè)元素沒(méi)賦值,它們將被置為0.
如果對(duì)array沒(méi)有做任何初始化操作,其所有元素處于未初始化狀態(tài)。
array類(lèi)支持以下STL標(biāo)準(zhǔn)方法:
l at, operator [] – 返回指定位置元素引用.
l back, front – 各自返回第一及最后一個(gè)元素位置引用;
l begin, cbegin, rbegin, crbegin -返回第一個(gè)元素迭代器;
l end, cend, rend, crend – 返回最后一個(gè)元素后一位的迭代器;
l empty – 判斷容器是否為空。僅當(dāng)數(shù)組大小為0時(shí)返回true;
l size, max_size – 返回array對(duì)象大小,該大小在編譯期間確定;
以下方法需要重點(diǎn)說(shuō)明:
array::assign 和 array:fill
這2個(gè)方法功能相同,實(shí)現(xiàn)將array所有元素賦值為一個(gè)給定值。此方法也可用來(lái)通過(guò)指定值替換array對(duì)象的所有元素。例如:
array<int,10> MyArray;MyArray.fill(40); // or 'assign'for_each(MyArray.cbegin(), MyArray.cend(),[](int n) { std::wcout << n << "\t";} );
將10個(gè)元素賦值為40,之后輸出到控制臺(tái)。
array::data
此方法返回?cái)?shù)組第一個(gè)元素地址。與普通數(shù)組相比(eg:int_array[N]),此方法類(lèi)似于表達(dá)式&int_array[0] 或者int_array。 此方法是由指針直接操作。const及非const方法都可用。例如:
int* pArray = MyArray.data();// Orauto pArray = MyArray.data();
array::swap(array&) 和swap(array&, array&)
交換兩個(gè)數(shù)組大小和類(lèi)型相同的array對(duì)象。第一個(gè)方法是非靜態(tài)方法,實(shí)現(xiàn)將本數(shù)組內(nèi)容與參數(shù)中的指定數(shù)組交換。第二個(gè)方法,攜帶2個(gè)array&參數(shù),互換內(nèi)容。例如:
typedef array<int,10> MyArrayType;MyArrayType Array1 = {1,2,4,8,16};MyArrayType Array2;Array2.assign(64);Array1.swap(Array2);// Or - swap(Array1, Array2);// Array1 - 64, 64...64// Array2 - 1,2,4,....0
如果試圖交換不同類(lèi)型數(shù)組,編譯器會(huì)報(bào)錯(cuò):
array<int,5> IntArrayOf5 = {1,2,3,4,5};array<int,4> IntArrayOf4 = {10,20,40};array<float,4> FloatArrayOf4;IntArrayOf5.swap(IntArrayOf4); // ERROR!swap(IntArrayOf4, FloatArrayOf4); // ERROR!
六種比較操作符
作為全局函數(shù)的==, !=, <, >, <=, 及>=可用來(lái)比較2個(gè)相同類(lèi)型的數(shù)組對(duì)象:
typedef array<int,10> MyArrayType;MyArrayType Array1 = {1,2,4,8,16};MyArrayType Array2;Array2.assign(64);if (Array2 == Array1)wcout << "Same";elsewcout << "Not Same";
結(jié)果輸出"Not Same" .
元組類(lèi)tuple
STL程序員都知道pair 結(jié)構(gòu),它用來(lái)包裝2個(gè)任意類(lèi)型的元素。除了maps,在其它地方這個(gè)結(jié)構(gòu)也非常有用,我們可以用來(lái)包裝2個(gè)元素,而不用定義一個(gè)結(jié)構(gòu)體。我們可通過(guò)first、 second變量取得這2個(gè)元素的值。
pair<string,int> NameAndAge;NameAndAge.first = "Intel";NameAndAge.second = 40;
程序員經(jīng)常typedef 它們,這樣變量就可以容易的申明并可將pair 傳給函數(shù)。
但是,如果你需要保證多于2個(gè)的元素,該怎么做呢?
通常,你會(huì)定義一個(gè)結(jié)構(gòu)體,或使用多重pair。這樣的格式并不能與STL無(wú)縫整合。
tuple 類(lèi)就是為此而生。這個(gè)類(lèi)允許將2至10個(gè)元素包裝在一起。
所有元素類(lèi)型都可不同,如果要加入自定義,其依賴(lài)的操作必須事先定義。tuple類(lèi)通過(guò)模版重載具體如何工作,已超出我的理解,這里我只說(shuō)明它可以完成什么,以及我們可以在哪里使用。
l 頭文件: <tuple>
l 命名空間: tr1. ‘using tr1::tuple’ 已包含在 std .
申明2個(gè)元素元組:
tuple<int,int> TwoElements;
在構(gòu)造函數(shù)中初始化:
tuple<int,int> TwoElement (400, 800);
如果初始化,則必須初始化所有元素,以下方式報(bào)錯(cuò):
tuple<int,int> TwoElement (400); // Second initializer missing
這個(gè)錯(cuò)誤可能不那么明顯,但是你應(yīng)該明白這個(gè)原則:必須初始化所有成員。
構(gòu)造之后的初始化并不簡(jiǎn)單。在pair中,有make_pair 來(lái)輔助pair的初始化。自然的,tuple也有相應(yīng)的輔助函數(shù)make_tuple。如果你已經(jīng)讀過(guò)或?qū)⒁xVC2010并行編程,你會(huì)發(fā)現(xiàn)C++庫(kù)中類(lèi)似的完成類(lèi)似的功能有其它新的make_函數(shù)。(譯注2:并行編程地址)
下面例子說(shuō)明如何初始化tuple對(duì)象:
TwoElement = make_tuple(400, 800);
跟tuple模版類(lèi)一樣,make_tuple 有傳入2至10個(gè)參數(shù)的重載函數(shù)版本。make_tuple充分利用C++0x中右值引用的思想,完美的支持STL新特性。它允許復(fù)用同一對(duì)象而不是調(diào)用復(fù)制構(gòu)造函數(shù)和賦值操作,以此提升整體性能。
我們可以結(jié)合make_tuple和auto關(guān)鍵詞來(lái)靈活的定義一個(gè)tuple:
auto Elements = make_tuple(20, 'X', 3.14159);// Eq: tuple<int, char, double> Elements(20, 'X', 3.14159);
如何訪問(wèn)tuple中的元素?
對(duì)于pair對(duì)象,我們都是簡(jiǎn)單的使用其內(nèi)部定義的變量first/second來(lái)訪問(wèn)元素。但是tuple類(lèi)中并沒(méi)有定義這樣的變量,我們需要通過(guò)輔助函數(shù)get來(lái)訪問(wèn)這些未命名變量。例如:
tuple<string, int, char> NameAgeGender("Gandhi", 52, 'M');int nAge = get<1>(NameAgeGender);
get<index>()中的可用索引必須在對(duì)象初始化的元素范圍之內(nèi)。索引以0為起點(diǎn)。在上述例子中,索引范圍為[0,2],get<1>用于訪問(wèn)NameAgeGender對(duì)象中的第二個(gè)元素,返回一個(gè)整型給nAge。
get函數(shù)的索引必須是一個(gè)常量編譯時(shí)的整型并在有效范圍內(nèi)。返回類(lèi)型的推導(dǎo)也是常量時(shí);以下代碼編譯器會(huì)報(bào)錯(cuò):
int nAge = get<0>(NameAgeGender);// ERROR - cannot convert from 'string' to 'int'
這樣也有助與發(fā)現(xiàn)潛在的代碼缺陷:
char cGender = get<1>(NameAgeGender); // Leve 4 C4244 warning - 'int' to 'char'// Should be get<2>
更重要的是,get可以賦值給auto關(guān)鍵詞:
auto sName = get<0>(NameAgeGender); // Type deduction - 'string'
對(duì)于非const類(lèi)型tuple對(duì)象,返回類(lèi)型為元組元素的引用,這樣,可以修改元素值:
// Modify Ageget<1>(NameAgeGender) = 79;
也可以將這個(gè)返回類(lèi)型放在另一個(gè)引用中,并在之后修改。使用auto關(guān)鍵詞也可行:
auto & rnAge = get<1>(NameAgeGender) ;rnAge = 79
需要指出的是,get函數(shù)同樣適用于array類(lèi):
array<char, 5> Vowels = {'A','E','I','o','U'};char c = get<1>(Vowels); // 'E'get<3>(Vowels) = 'O'; // Modifyget<10><Vowels); // ERROR - Out of range!
tie函數(shù)
這個(gè)函數(shù)實(shí)現(xiàn)make_tuple函數(shù)的逆操作。使用這個(gè)函數(shù),你可以用一個(gè)tuple對(duì)象來(lái)初始化一組變量。看例子:
tuple<string, int, char> NameAgeGender("Gandhi", 52, 'M');string sName;int nAge;char cSex;tie(sName, nAge, cSex) = NameAgeGender;
以上代碼將這3個(gè)變量對(duì)應(yīng)的設(shè)置為值 "Gandhi", 52, and ‘M’。我想tie是否可以用于取代make_tuple?結(jié)果證明不行:
tuple<string, int, char> NameAgeGender;NameAgeGender = tie("Gates", 46, 'M'); // make_tuplestring sName; int nAge; char cSex;make_tuple(sName, nAge, cSex) = NameAgeGender; // NO error. See below.
tie函數(shù)返回tuple對(duì)象的引用;make_tuple則是創(chuàng)建一個(gè)對(duì)象,返回的并非引用。上面最后一行試圖修改一個(gè)臨時(shí)創(chuàng)建的tuple對(duì)象,編譯器不報(bào)錯(cuò),卻并不能得到正確結(jié)果。因此,最好還是按照它們?cè)O(shè)計(jì)的功能來(lái)使用這2個(gè)函數(shù)。
六種關(guān)系操作符
與array類(lèi)一樣,tuple類(lèi)中同樣實(shí)現(xiàn)了6種操作符的功能。所有的重載版本都要求作關(guān)系操作的兩個(gè)tuple對(duì)象必須是同類(lèi)型的(所包含的元素的對(duì)應(yīng)位置的類(lèi)型必須相同)。
(未完待續(xù))
【注1】TR1:
C++ Technical Report 1 (TR1)是ISO/IEC TR 19768, C++ Library Extensions(函式庫(kù)擴(kuò)充)的一般名稱(chēng)。TR1是一份文件,內(nèi)容提出了對(duì)C++標(biāo)準(zhǔn)函式庫(kù)的追加項(xiàng)目。這些追加項(xiàng)目包括了正則表達(dá)式、智能指針、哈希表、隨機(jī)數(shù)生成器等。TR1自己并非標(biāo)準(zhǔn),他是一份草稿文件。然而他所提出的項(xiàng)目很有可能成為下次的官方標(biāo)準(zhǔn)。這份文件的目標(biāo)在于「為擴(kuò)充的C++標(biāo)準(zhǔn)函式庫(kù)建立更為廣泛的現(xiàn)成實(shí)作品」。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
C++中STL各容器詳解1
STL模板總結(jié)
STL set 的詳細(xì)用法
stl容器學(xué)習(xí)總結(jié)
泛型編程與設(shè)計(jì)新思維
C 容器及選用總結(jié)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服