1. 程式人生 > >stl的一些注意地方

stl的一些注意地方

容器是用來儲存和組織其他物件的物件

標頭檔案內容
vector表示一個必要時可自動增加容量的陣列
array陣列容器優於vector<>的一個優點是,它可以完全在棧上分配,而vector<>總是需要訪問堆
deque增加了向容器開頭新增元素的能力
forward_list單向連結串列,以前向方式處理連結串列中的元素,就比List快
mapmap<K,T>是關聯容器,用關聯鍵(型別為k)儲存T型別的每個元素
unordered_map類似於map但是該容器中的鍵/物件對沒有特定的順序
set是一個對映,各物件作為自身的鍵,所有物件必須唯一,並且無法在集合中修改物件
unordered_set類似於set,但元素進行無序排列
bitset定義表示固定位數的bitset<T>類模板,通常用來儲存表示一組狀態或條件的標誌

大多數STL容器都會自動增大其容量來容納所儲存的元素。這些容器的附加記憶體用一個名為分配器的物件來提供,分配器一般會在需要時分配堆上的記憶體,也可以通過一個額外的型別形參,提供自己的分配器型別。

例如,建立向量的vector<T>模板實際上是一個vector<T,A<T>>模板,第二個型別的形參預設分配器型別是allocator<T>

容器介面卡是包裝了現有STL容器類的模板類,如佇列,棧

迭代器物件的行為和指標相似,它對於訪問除容器介面卡定義內容之外所有STL容器的內容非常重要,容器介面卡不支援迭代器

得到的迭代器型別取決於使用的容器的種類

智慧指標用於動態分配記憶體物件

unique_ptr<T>型別定義了一個物件,用來儲存唯一物件的指標

shared_ptr<T>型別指標可以同時有多個shared_ptr物件指向相同的物件,並且引用該物件的shared_ptr物件數量會記錄下來,指向同一個物件的所有shared_ptr物件必須在他們所指向的物件刪除之前刪除,當最後一個指向給定物件的shared_ptr物件刪除後,它指向的物件才能刪除且釋放其記憶體

weak_ptr<T>型別儲存了一個連線到shared_ptr的指標,weak_ptr<T>不會遞增或遞減所連結shared_ptr的引用數,所以可以在引用它的最後一個shared_ptr刪除之前,不會刪除物件,釋放其記憶體。weak_ptr物件就是為避免引用迴圈問題而設計的,使用weak_ptr物件指向一個shard_ptr物件所指向的物件,就可以避免引用迴圈。只需要刪除shared_ptr物件,它指向的物件就能刪除,接著與shared_ptr相關的weak_ptr物件就變為無效。

make_unique<T>()函式模板在堆上建立了一個新的T物件,在建立一個指向T物件的unique_ptr<T>物件如:

auto pBox=std::make_unique<CBox>(2.0,3.0,4.0);

同理,最好使用make_shared<T>()函式在堆上建立一個T型別的物件,再返回一個指向它的shared_ptr<T>物件,因為記憶體分配更加高效。

有時需要訪問智慧指標包含的指標:這稱為裸指標,呼叫智慧指標物件的get()成員會返回裸指標,呼叫reset()會把裸指標重置空

對智慧指標的轉化需要使用static_pointer_cast,dynameic_pointer_cast和const_pointer_cast,在memory標頭檔案中定義。

演算法在algorithm和numeric標頭檔案中定義。

函式介面卡是允許合併函式物件以產生一個更復雜的函式物件的函式模板

vector的函式:capacity()返回當前容量,max_size()返回向量中元素的最大可能數目。resize()可以增加或減小向量大小,front()返回第一個元素,back()返回最後一個元素,pop_back()刪除最後一個元素,clear()刪除所有元素,insert()插入新元素,emplace()和emplace_back用於在向量中插入物件時就地建立它,erase()可以刪除向量中任何位置的一個或多個元素。assign用另一序列替換一個向量中的全部內容,或者用給定數量的物件例項替換向量內容。

functional標頭檔案定義比較謂詞的完整函式物件集合,包括:less<T> less_equal<T> equal<T> greater_equal<T> greater<T>,用作sort函式的第三個引數

陣列容器的表達方式

template<class T,size_t N>
void listValues(const array<T,N>& data)
{
  ..
}

使用numeric標頭檔案定義的accumulate()模板函式可以求陣列之和,第一個引數為開始位置,第二結束位置,第三個相加後賦予的值。

雙端佇列的前段新增元素的函式為push_front(),刪除第一個元素為pop_front

列表的begin()和end()函式返回的是迭代器是雙向迭代器,只能使用遞增或遞減運算子修改雙向迭代器的值。

列表函式advance()函式來遞增迭代器,將第一個實參指定的迭代器遞增第二個實參指定的次數。emplace()在迭代器指定的 上構建一個元素,emplace_front()在列表開頭構建一個元素,emplace_back()在列表結尾構建一個元素。remove()函式從列表中刪除匹配特定值的元素。unique()函式將消除列表中相鄰的重複元素,如果先排序,即可確保所有元素的唯一。splice()函式可以刪除一個列表的全部或一部分,並將它插到另一個列表中,第一個實參為迭代器,指定插入元素的位置,第二個是插入的元素來自的列表,將會刪除原來的位置的元素。merge()函式刪除作為一個實參提供的列表中的元素,並將它們插入呼叫該函式的列表中,在呼叫之前,2個列表都必須適當地排序。例如:

list<int> numbers{1,2,3};//1 2 3
list<int> values{2,3,4,5,6,7,8};//2 3 4 5 6 7 8
numbers.merge(values);//1 2 2 3 3 4 5 6 7 8

remove_if()函式基於應用一元謂詞的結果來刪除列表中的元素。一元謂詞是一個應用到單個實參的函式物件,它返回一個bool值true或false,如果向一個元素應用謂詞的結果是true,就會從列表刪除該元素。通常我們會定義自己的謂詞。基類模板如下:

template<class _Arg,class _Result>
struct unary_function
{
  typedef _Arg argument_type;
  typedef _Result result_type;
};

template<class T>class is_negative:public std::unary_function<T,bool>
{
   public:
    result_type operator()(argument_type& value)
{
  return value<0;
 }
};

forward_list,每個元素都包含指向下一個元素的指標,只能向前遍歷元素。before_begin()函式返回一個迭代器,指向第一個元素前面的位置,distance()返回元素個數。forward_list<T>容器提供的效能比List<t>容器好得多,只有一個連結要維護,使其操作起來更快,且不需要跟蹤元素的個數。

priority_queue<t>容器是一個佇列,它的頂部總是具有最大或最高優先順序的元素,不過優先順序佇列不能訪問佇列後端的元素,只能訪問前端的元素。

tuple<>類模板定義在tuple標頭檔案中國,此模板對於array<>容器是一個有用的輔助,tuple<>物件封裝了很多不同的項,這些項可以具有不同的型別。例子如下:

using Record=std::tuple<int,std::string,std::string,int>

std::array<Record,5>personal{Record{1001,"joan","jetson",35},
Record{1002,"jim","jones",26},
Record{1003,"june","jello",31},
Record{1004,"jack","jester",39}};

要訪問元祖中的欄位,需要使用get()模板函式,注意get()函式模板的型別形參必須是一個編譯時常量。

關聯容器(如map<K,T>)最重要的特性是無須搜尋就可以檢索特定的物件,關聯容器內T型別物件的位置由於物件一起提供的型別為K的鍵確定,因此只要提供適當的鍵,就可以快速地檢索任何物件。當建立map<K,T>容器時,K是鍵的型別,用於儲存T型別的關聯物件,鍵/物件對會儲存為pair<K,T>型別的物件,pair<K,T>在utility標頭檔案中定義。可以通過成員first和second訪問一個對中的元素。.first為鍵,.second為物件。insert()函式返回的值也是一個對,對中第一個物件是迭代器,第二個物件是bool型別值,成功為true,失敗為false;

iterator標頭檔案定義流迭代器的幾個模板,用於將資料從源傳到目的地,流迭代器作為指向輸入流或輸出流的指標,可以在流和任何使用迭代器的源或目的地之間傳輸資料,如演算法。

std::istream_iterator<int> numbersInput{std::cin};//建立輸入流迭代器

sstream標頭檔案定義了basic_istringstream<T>模板,這個模板定義了可以訪問流緩衝區中的資料物件型別。

std::string data{"2.4 2.5 3.6 2.1 6.7 6.8 94 95 1.1 1.4 32"};
std::istringstream input{data};
std::istream_iterator<double>begin (input),end;//由於從string物件data中建立istringstream物件,因為可以像流一樣從data中讀取資料。

copy函式將迭代之間指定的實參複製到輸出流迭代器中。如:

std::ostream_iterator<int> out{std::cout};
int data[]{1,2,3,4,5,6,7,8,9};
std::copy(std::cbegin(data),std::cend(data),out);

not2<>()模板函式,它建立一個二元謂詞,它是傳遞為實參的函式物件定義的二元謂詞的負值。例如,not2(less<int>())建立一個二元謂詞來比較Int型別的物件,如果左運算元不小於右運算元,則返回true。

函式物件模板說明
plus<T>計算兩個T型別元素的和
minus<T>通過從第一個運算元中減去第二個運算元來計算他們之間的差
Multiplies<T>計算兩個T型別元素的積
divides<T>用第一個T型別運算元除以第二個T型別運算元
modulus<T>計算第一個運算元除以第二個運算元後的餘數
negate<T>返回T型別運算元的負值
上述的這些都是通過transform來使用的

transform的這個版本將一元函式f應用到迭代器begin,end指定的範圍中的所有元素,並從迭代器result指定的位置開始儲存結果

OutputIterator transform(InputIterator begin,InputIterator end,
OutputIterator result,UnaryFunction f)

由begin1和end1指定的範圍表示最後一個實參指定的二元函式f的左運算元集合表示右運算元的範圍從begin2迭代器指定的位置開始,這個範圍不需要提供end迭代器,因為這個範圍的元素數量必須與begin1和end1指定的範圍中的元素個數相同,結果將從resut迭代器位置開始儲存在這個範圍內,如果希望結果儲存回該範圍中,result迭代器可以與begin1相同,但是它一定不能是begin1和end1之間的其他任何位置。

transform(InputIterator1,begin1,InputIterator end1,InputIterator2 begin2,OutputIterator result,BinaryFunction f)

靜態斷言可以在編譯期間檢測用法錯誤,形式如下:

static_assert(constant_expression,string_literal);

constant_expression,應的到一個可轉換為bool型別的值,如果結果是true,就什麼都不做,如果它是false,編譯器就顯示字元

λ表示式定義一個沒有名稱,也不需要顯式類定義的函式物件,λ表示式作為一種手段,用來將函式作為實參傳遞到另一個函式。λ形參有幾個限制,不能指定λ表示式形參的預設值,形參列表的長度不能變,預設返回型別會返回值的型別,也可指定如:

[](double x)->double{return x*x*x;}

f方括號之間是=,則λ主體可以按值訪問封閉作用域中的所有自動變數,即變數值可用在λ,但不會修改原始的變數,如果是&引用,則可以訪問加修改。按值訪問中,想修改外面的變數需要加上mutable。

可以將無狀態的λ賦予函式指標變數,這樣就給λ表示式指定了名稱,如

auto sum=[](int a,int b){return a+b;};
cout<<sum(5,10);//直接呼叫


相關推薦

stl一些注意地方

容器是用來儲存和組織其他物件的物件標頭檔案內容vector表示一個必要時可自動增加容量的陣列array陣列容器優於vector<>的一個優點是,它可以完全在棧上分配,而vector<>總是需要訪問堆deque增加了向容器開頭新增元素的能力forward

python資料儲存之列表:一些注意地方

1.常用列表的列表推導式 a = [i for i in range(n)]  # 會生成關於i的一個列表,其中可以對i進行判斷篩選,或者進行其他操作 在列表資料清洗可以使用列表推導式,例如簡單的一個列表元素資料的清洗操作 a = [1,2,3,4]   # 對列表a中的資

關於用FragmentTabHost的實現底部導航欄的一些注意地方~

參考程式碼出處:http://blog.csdn.net/yangyu20121224/article/details/9016223 其中有些地方用的不是太明白,自己在Demo中好好好折騰了下,算是弄白了一些沒看懂得東西,現在記下來,以便備忘~ 一:改進後的專案效果圖: 自

maven專案一些注意地方

1、jdk編譯版本全域性配置:setting.xml中配置<!--配置maven 預設jdk編譯版本--><profile><id>jdk18</id>  <activation>  <activeByDefa

hibernate3 二級快取一些注意地方

  1.Hibernate3的二級快取和session級別的快取一樣都只對實體物件做快取,不對屬性級別的查詢做快取;二級快取的生命週期和sessionFactory的生命週期是一樣的,sessionFactory可以管理二級快取;     2.sessionFactory級別

Activity生命週期一些注意地方

在MainActivity去啟動一個新的Activity時,如果是用startActivity,這個時候MainActivity的生命週期是處於onPause狀態,但是如果是startActivityForResult

try catch異常的一些注意地方

網上的一些總結記錄:1 try、catch、finally語句中,在如果try語句有return語句,則返回的之後當前try中變數此時對應的值,此後對變數做任何的修改,都不影響try中return的返回值2 如果finally塊中有return 語句,則返回try或catch

WTForms做更新時的一些注意

因為做“新增”和“更新”操作時的內容都是類似的,所以可以定義一個FlaskForm類然後在“新增”和“更新”模板中都使用該類進行渲染: MovieForm(FlaskForm): class MovieForm(FlaskForm): tag_list = Tag.query.al

Android中用命令列檢視內嵌資料庫SQLite3的一些注意事項

進入手機模擬器的shell環境    連線好手機模擬器後,通過Android Studio的Teminal終端直接進入shell環境          adb shell //進入手機模擬器的shell環境 s

關於浮動的一些注意事項

關於浮動:   巨集觀地講,我們的web頁面和photoshop等設計軟體有本質的區別:web頁面的製作,是個“流”,必須從上而下,像“織毛衣”。而設計軟體,想往哪裡畫個東西,都能畫。   行內元素和塊級元素的區別:(非常重要) 行內元素: 與其他行內元素並排; 不能設定寬、高。預設的寬度,

搜尋引擎優化的一些注意事項

4、 評價網站實用性有哪些原則  網站速度 搜尋結果中的點選率 使用者停留時間、訪問時長 使用者跳出率 回頭客的數量 註冊使用者和非註冊使用者的比例 使用者訪問來源分佈 5、什麼是pr值 PR即PageRank,也就是網頁級別

darknet訓練yolov3時的一些注意事項

  訓練需要用到的檔案: 1)       .data檔案。該檔案包含一些配置資訊,具體為訓練的總類別數,訓練資料和驗證資料的路徑,類別名稱,模型存放路徑等。 例如coco.data classes= 80 # 訓練總類別數

Pycharm呼叫tensorflow的一些注意

其實,Pycharm功能非常強大,使用起來非常的簡便,但遇到一些小問題,還是值得注意的. 現在有很多小夥伴在研究深度學習都會接觸到各種深度框架, tensorflow 算是比較常見的一種. 在使用Pycharm呼叫tensorflow的時候會報如下錯誤: ImportErro

char陣列和char指標的使用區別和一些注意事項

const用法 const char* p;表示p是一個指向常量字元的指標 char* const p;表示p是一個指向字元的常量指標,p是不允許改變的 另外要注意的是 const char* p等價於 char const *p 也就是說const描述char和*p是等價的

關於Visual Studio 2013 配置OpenCV 的一些注意事項和執行問題

1.在visual studio上配置opencv的依賴項和執行庫. 1.開啟Vs,檔案->新建->專案 2. visual c++ -> Win32控制檯應用程式->確定 (劃線的內容可以根據自己習慣更改) 3.直接下一步 4.選中空專案這個選項,然

Unity3D UGUI的一些注意

     網上找了很多資料, 都沒有詳細的講解四個座標系的一些細節。這裡我想記錄一下。 1. 初學者們常常會把GetComponent<RectTransform>().position 和 transform.position 當成是兩個東西,其實他們

open函式的一些注意點及r,r+,w,w+,a,a+的區別

open函式的一些注意點 open(file[, mode[, buffering[, encoding[, errors[, newline]]]]]) (1)file檔案路徑及名稱,需要加引號如”/Users/macxunlei/Desktop/a.txt” (2)mode檔案開啟模式,r、w、a為開啟檔

Springboot 中 Redis快取使用 @Cacheable不生效的原因,以及@Cacheable 的一些注意

Springboot 中 Redis快取使用 @Cacheable不生效的原因,以及@Cacheable 的一些注意點 1、有如下程式碼 // get 方法呼叫了 stockGive 方法,stockGive 方法使用了快取 // 但是每次執行get 方

啟用SAP Fiori之前的一些注意事項

Prerequisites Checklist Before you can install and configure SAP Fiori apps, you must ensure that the prerequisite software is installed and R

有關索引建立的一些注意事項

在建立索引以後,頻繁的對資料庫表進行delete 、update、insert 操作,那麼索引的效率會變慢,比如一天內表資料增加百萬條,並且是在含有索引的情況下,處理這種問題就要考慮索引建立與否,以及索引的管理 索引建立的型別,一般會建B-tree索引 可以在資料量少的情況下不建