C++STL

checha發表於2024-07-23

介紹

C++ 標準模板庫(Standard Template Library,STL)是一套功能強大的 C++ 模板類和函式的集合,它提供了一系列通用的、可複用的演算法和資料結構。

STL 的設計基於泛型程式設計,這意味著使用模板可以編寫出獨立於任何特定資料型別的程式碼。
泛型程式設計:不使用具體資料型別(int、double、float等),而是使用一種通用型別來進行程式設計的方法

STL 分為多個元件,包括容器(Containers)、迭代器(Iterators)、演算法(Algorithms)、函式物件(Function Objects)和介面卡(Adapters)等。

使用 STL 的好處:

程式碼複用:STL 提供了大量的通用資料結構和演算法,可以減少重複編寫程式碼的工作。
效能最佳化:STL 中的演算法和資料結構都經過了最佳化,以提供最佳的效能。
泛型程式設計:使用模板,STL 支援泛型程式設計,使得演算法和資料結構可以適用於任何資料型別。
易於維護:STL 的設計使得程式碼更加模組化,易於閱讀和維護。

重要元件

C++ 標準模板庫的核心包括以下重要元件:

元件 描述
容器(Containers) 容器是 STL 中最基本的元件之一,提供了各種資料結構,包括向量(vector)、連結串列(list)、佇列(queue)、棧(stack)、集合(set)、對映(map)等。這些容器具有不同的特性和用途,可以根據實際需求選擇合適的容器。
演算法(Algorithms) STL 提供了大量的演算法,用於對容器中的元素進行各種操作,包括排序、搜尋、複製、移動、變換等。這些演算法在使用時不需要關心容器的具體型別,只需要指定要操作的範圍即可。
迭代器(iterators) 迭代器用於遍歷容器中的元素,允許以統一的方式訪問容器中的元素,而不用關心容器的內部實現細節。STL 提供了多種型別的迭代器,包括隨機訪問迭代器、雙向迭代器、前向迭代器和輸入輸出迭代器等。
函式物件(Function Objects) 函式物件是可以像函式一樣呼叫的物件,可以用於演算法中的各種操作。STL 提供了多種函式物件,包括一元函式物件、二元函式物件、謂詞等,可以滿足不同的需求。
介面卡(Adapters) 介面卡用於將一種容器或迭代器適配成另一種容器或迭代器,以滿足特定的需求。STL 提供了多種介面卡,包括棧介面卡(stack adapter)、佇列介面卡(queue adapter)和優先佇列介面卡(priority queue adapter)等。

這些個元件都帶有豐富的預定義函式,幫助我們透過簡單的方式處理複雜的任務。

容器

容器是用來儲存資料的序列,它們提供了不同的儲存方式和訪問模式。

STL 中的容器可以分為三類:

1、序列容器:儲存元素的序列,允許雙向遍歷。

std::vector:動態陣列,支援快速隨機訪問。
std::deque:雙端佇列,支援快速插入和刪除。
std::list:連結串列,支援快速插入和刪除,但不支援隨機訪問。
2、關聯容器:儲存鍵值對,每個元素都有一個鍵(key)和一個值(value),並且透過鍵來組織元素。

std::set:集合,不允許重複元素。
std::multiset:多重集合,允許多個元素具有相同的鍵。
std::map:對映,每個鍵對映到一個值。
std::multimap:多重對映,允許多個鍵對映到相同的值。
3、無序容器(C++11 引入):雜湊表,支援快速的查詢、插入和刪除。

std::unordered_set:無序集合。
std::unordered_multiset:無序多重集合。
std::unordered_map:無序對映。
std::unordered_multimap:無序多重對映。

標頭檔案

使用C++標準模板庫時需要引入一些標頭檔案:

容器 (Containers)

vector: #include <vector>
deque: #include <deque>
list: #include <list>
array: #include <array>
forward_list: #include <forward_list>
set: #include <set>
multiset: #include <set>
map: #include <map>
multimap: #include <map>
unordered_set: #include <unordered_set>
unordered_multiset: #include <unordered_set>
unordered_map: #include <unordered_map>
unordered_multimap: #include <unordered_map>

演算法 (Algorithms)

algorithm: #include <algorithm>

迭代器 (Iterators)

iterator: #include <iterator>

函式物件 (Function Objects) 和 Lambda 表示式

functional: #include <functional>

容器介面卡 (Container Adapters)

stack: #include <stack>
queue: #include <queue>
priority_queue: #include <queue>
下面的程式演示了向量容器(一個 C++ 標準的模板),它與陣列十分相似,唯一不同的是,向量在需要擴充套件大小的時候,會自動處理它自己的儲存需求:
例項

#include <iostream>
#include <vector>
using namespace std;

int main()
{
   // 建立一個向量儲存 int
   vector<int> vec; 
   int i;

   // 顯示 vec 的原始大小
   cout << "vector size = " << vec.size() << endl;

   // 推入 5 個值到向量中
   for(i = 0; i < 5; i++){
      vec.push_back(i);
   }

   // 顯示 vec 擴充套件後的大小
   cout << "extended vector size = " << vec.size() << endl;

   // 訪問向量中的 5 個值
   for(i = 0; i < 5; i++){
      cout << "value of vec [" << i << "] = " << vec[i] << endl;
   }

   // 使用迭代器 iterator 訪問值
   vector<int>::iterator v = vec.begin();
   while( v != vec.end()) {
      cout << "value of v = " << *v << endl;
      v++;
   }

   return 0;
}
/*
當上面的程式碼被編譯和執行時,它會產生下列結果:

vector size = 0
extended vector size = 5
value of vec [0] = 0
value of vec [1] = 1
value of vec [2] = 2
value of vec [3] = 3
value of vec [4] = 4
value of v = 0
value of v = 1
value of v = 2
value of v = 3
value of v = 4
*/

關於上面例項中所使用的各種函式,有幾點要注意:

push_back( ) 成員函式在向量的末尾插入值,如果有必要會擴充套件向量的大小。
size( ) 函式顯示向量的大小。
begin( ) 函式返回一個指向向量開頭的迭代器。
end( ) 函式返回一個指向向量末尾的迭代器。