現代 C++ 容器深度解析及實踐

一、線性容器:std::array 與 std::forward_list
1. std::array:固定大小的高效容器

在傳統 C++ 中,數組與 vector 的抉擇常讓人糾結:數組缺乏安全檢查,vector 存在動態擴容開銷。C++11 引入的std::array完美平衡了兩者優勢:

  • 特性解析

    • 編譯期確定大小,內存連續分配,訪問效率與 C 數組一致;
    • 封裝了迭代器、size ()、empty () 等標準接口,兼容 STL 算法;
    • 避免 vector 擴容時的重分配開銷,適合已知容量的場景。
  • 代碼示例

#include <array>
#include <iostream>
#include <algorithm>int main() {// 初始化與基本操作std::array<int, 4> arr = {1, 3, 2, 4};std::cout << "數組大小:" << arr.size() << std::endl;// 迭代器與算法支持std::sort(arr.begin(), arr.end());for (const auto& num : arr) {std::cout << num << " ";}// 與C接口兼容int* c_ptr = arr.data();return 0;
}

  • 使用場景
    • 存儲固定長度的配置項(如哈希表桶數量);
    • 替代局部 C 數組,避免越界風險;
    • 作為函數參數傳遞時,避免退化為指針導致的長度丟失。
2. std::forward_list:單向鏈表的輕量選擇

與雙向鏈表std::list相比,std::forward_list采用單向鏈表實現,犧牲反向遍歷能力換取更緊湊的內存布局:

  • 核心優勢

    • 節點僅含 next 指針,空間利用率比 list 高約 30%;
    • 支持 O (1) 復雜度的頭部插入 / 刪除;
    • 無 size () 方法(需遍歷計算長度),適合 “添加 - 遍歷” 場景。
  • 典型應用

#include <forward_list>int main() {std::forward_list<int> flist;flist.push_front(1);flist.push_front(2);// 遍歷與刪除auto it = flist.begin();if (it != flist.end()) {flist.erase_after(it); // 刪除頭節點后的元素}// 合并鏈表std::forward_list<int> another = {3, 4};flist.merge(another);return 0;
}
二、無序容器:哈希表的標準化實現

傳統std::map/std::set基于紅黑樹實現,插入與查找復雜度為 O (logN)。C++11 引入的無序容器基于哈希表,平均復雜度降至 O (1):

1. 接口與性能對比

std::unordered_map為例,與std::map的關鍵差異:

特性std::mapstd::unordered_map
底層結構紅黑樹哈希表 + 鏈表(解決沖突)
插入復雜度O(logN)平均 O (1),最壞 O (N)
遍歷順序按鍵有序無固定順序
內存開銷每個節點含左右指針哈希桶 + 鏈表指針
適用場景需有序遍歷、范圍查詢高頻查找、無序存儲
2. 實戰技巧
  • 哈希函數定制
#include <unordered_map>
#include <string>struct Person {std::string name;int age;bool operator==(const Person& other) const {return name == other.name && age == other.age;}
};// 為自定義類型特化哈希函數
namespace std {template<>struct hash<Person> {size_t operator()(const Person& p) const {return hash<string>()(p.name) ^ (hash<int>()(p.age) << 1);}};
}int main() {std::unordered_map<Person, string> person_map;return 0;
}

  • 性能優化點
    • 預分配桶數量:reserve(n)避免動態擴容導致的重哈希;
    • 減少哈希沖突:選擇分布均勻的哈希函數,或使用std::unordered_mapmax_load_factor調整負載因子;
    • 避免頻繁修改鍵值:修改鍵值可能導致哈希位置變化,需重新插入。
三、元組 std::tuple:多類型數據的聚合神器

傳統std::pair僅能存儲兩個元素,std::tuple則支持任意數量、任意類型的元素組合:

1. 基礎操作與解包
#include <tuple>
#include <iostream>int main() {// 創建元組auto student = std::make_tuple(95, 'A', "張三");// 訪問元素(編譯期索引)int score = std::get<0>(student);char grade = std::get<1>(student);// 結構化綁定(C++17特性)auto [s, g, name] = student;std::cout << "姓名:" << name << ",成績:" << s << std::endl;// 元組合并auto new_tuple = std::tuple_cat(student, std::make_tuple(18));return 0;
}
2. 運行期索引與泛型處理

C++17 引入的std::variant配合元組,實現運行期動態索引:

#include <variant>
#include <tuple>
#include <iostream>// 運行期索引元組元素
template <size_t N, typename... T>
constexpr std::variant<T...> tuple_at(const std::tuple<T...>& tpl, size_t index) {if constexpr (N >= sizeof...(T)) {throw std::out_of_range("索引越界");}if (index == N) {return std::variant<T...>{std::in_place_index<N>, std::get<N>(tpl)};}return tuple_at<(N < sizeof...(T) - 1 ? N + 1 : 0)>(tpl, index);
}int main() {auto t = std::make_tuple(10, "hello", 3.14);size_t idx = 1;std::visit([](auto&& x) { std::cout << x << std::endl; }, tuple_at<0>(t, idx));return 0;
}
3. 實用場景
  • 函數多返回值(替代結構體或 pair 嵌套);
  • 數據庫記錄映射(一行數據映射為元組);
  • 泛型編程中的參數包處理(如日志函數的可變參數格式化)。
四、容器選擇與性能優化
  1. 按場景選容器

    • 需有序遍歷:std::map/std::set
    • 高頻查找:std::unordered_map/std::unordered_set
    • 固定大小數組:std::array
    • 頻繁頭部插入:std::forward_list
  2. 性能優化 Tips

    • std::vector預留空間:reserve()避免多次擴容;
    • 優先使用emplace_back替代push_back+ 構造;
    • std::unordered_map,合理設置哈希函數與負載因子;
    • 元組作為函數返回值時,利用std::move避免拷貝。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/86746.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/86746.shtml
英文地址,請注明出處:http://en.pswp.cn/web/86746.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據集|豬姿態檢測PigBehaviorRecognitionDataset

數據集|豬姿態檢測PigBehaviorRecognitionDataset 一、數據集介紹1.1 介紹1.2 用途1.3 數據集統計 二、樣本類別介紹1. Lying&#xff08;躺臥&#xff09;2. Sleeping&#xff08;睡眠&#xff09;3. Investigating&#xff08;探索&#xff09;4. Eating&#xff08;進食&…

Vue-13-前端框架Vue之應用基礎路由器的使用步驟

文章目錄 1 路由和路由器2 基本切換效果2.1 App.vue(根組件)2.2 components(子組件)2.2.1 Home.vue(首頁)2.2.2 News.vue(新聞)2.2.3 About.vue(關于)2.3 路由器2.3.1 router/index.ts2.3.2 main.ts2.4 效果展示2.5 程序流程3 筆記3.1 路由組件和一般組件3.1.1 Header.vue(一般…

GaussDB實例級自動備份策略:構建數據安全的“自動防護網”

GaussDB實例級自動備份策略&#xff1a;構建數據安全的“自動防護網” 在數字化轉型的浪潮中&#xff0c;數據庫作為企業核心數據的載體&#xff0c;其安全性與可恢復性直接關系到業務的連續性。對于分布式數據庫GaussDB而言&#xff0c;實例級自動備份策略是保障數據安全的關…

推薦幾本關于網絡安全的書

對于網絡安全從業者、相關專業學生以及對網絡安全感興趣的人士而言&#xff0c;掌握扎實的網絡安全知識和技能至關重要。以下推薦的幾本網絡安全書籍&#xff0c;涵蓋了網絡安全領域的多個重要方面&#xff0c;是學習和研究網絡安全的優質參考資料。 1、攻擊網絡協議&#xff…

工業4.0浪潮下PROFIBUS DP轉ETHERNET/IP在軋鋼廠的創新實踐

在工業自動化4.0推動制造業向智能化升級的背景下&#xff0c;軋鋼廠生產對設備互聯與數據協同提出更高要求。PROFIBUS DP與ETHERNET/IP協議的特性差異&#xff0c;制約著西門子PLC與工業測距儀等設備的高效協作。通過協議轉換技術實現兩者互通&#xff0c;為軋鋼生產線注入智能…

從0開始學習R語言--Day31--概率圖模型

在探究變量之間的相關性時&#xff0c;由于并不是每次分析數據時所用的樣本集都能囊括所有的情況&#xff0c;所以單純從樣本集去下判斷會有武斷的嫌疑&#xff1b;同樣的&#xff0c;我們有時候也想要在數據樣本不夠全面時就能對結果有個大概的了解。 例如醫生在給患者做診斷…

微信小程序進度條progress支持漸變色

微信小程序自帶進度條progress支持漸變色代碼 .wx-progress-inner-bar {border-radius: 8rpx !important;background: linear-gradient(90deg, #FFD26E 8%, #ED0700 100%) !important; }<view class"progress-box"><progress percent"80" back…

Linux內核網絡協議棧深度解析:面向連接的INET套接字實現

深入剖析Linux內核中TCP連接管理的核心機制,揭示高效網絡通信的實現奧秘。 一、源地址匹配:連接建立的第一道關卡 在TCP連接建立過程中,內核需要驗證源地址是否匹配。inet_rcv_saddr_equal()函數是實現這一功能的核心,它巧妙地處理了IPv4/IPv6雙棧環境: bool inet_rcv_s…

Vue 項目中 Excel 導入導出功能筆記

功能概述 該代碼實現了 Vue 項目中 Excel 文件的三大核心功能&#xff1a; Excel 導入&#xff1a;上傳文件并解析數據&#xff0c;刷新表格展示。模板下載&#xff1a;獲取并下載標準 Excel 模板文件。數據導出&#xff1a;將表格數據按多級表頭結構導出為 Excel 文件。 一…

71. 簡化路徑 —day94

前言&#xff1a; 作者&#xff1a;神的孩子在歌唱 一個算法小菜雞 大家好&#xff0c;我叫智 71. 簡化路徑 給你一個字符串 path &#xff0c;表示指向某一文件或目錄的 Unix 風格 絕對路徑 &#xff08;以 / 開頭&#xff09;&#xff0c;請你將其轉化為 更加簡潔的規范路徑…

Linux系統編程 | 互斥鎖

1、什么是互斥鎖 如果信號量的值最多為 1&#xff0c;那實際上相當于一個共享資源在任意時刻最多只能有一個線程在訪問&#xff0c;這樣的邏輯被稱為“互斥”。這時&#xff0c;有一種更加方便和語義更加準確的工具來滿足這種邏輯&#xff0c;他就是互斥鎖。 “鎖”是一種非常形…

數據文件寫入技術詳解:從CSV到Excel的ETL流程優化

文章大綱&#xff1a; 引言&#xff1a;數據文件寫入在ETL流程中的重要性 在現代數據處理中&#xff0c;ETL&#xff08;提取、轉換、加載&#xff09;流程是數據分析和業務決策的核心環節&#xff0c;而數據文件寫入作為ETL的最后一步&#xff0c;扮演著至關重要的角色。它不…

在Cline中使用Gemini CLI,圖形化界面操作:從命令行到可視化操作的全新體驗,爽炸天!

在軟件開發的進程中&#xff0c;命令行工具雖功能強大&#xff0c;但對部分開發者而言&#xff0c;圖形化界面的直觀與便捷性有著獨特魅力。此前&#xff0c;Cline 新版本集成 Gemini CLI 的消息在開發者社群引發熱議&#xff0c;尤其對于偏好圖形界面的開發者來說&#xff0c;…

正交視圖三維重建 筆記 2d線到3d線

這種代碼怎么寫好&#xff0c;x1tx1 x2tx2 x1x2在一條線上tx2和tx1在一條線上輸出x1 y1 ty1&#xff0c;x2 y2 ty2 線過的點 的集合 俯視圖找深度 測試一下 目標 四條線變一條線 復雜度賊大跑起來賊慢 加了16000條 去重 for (const [x1, y1, x2, y2, lineId, type] of front…

【耳機】IEM 前腔 后腔 泄壓孔 -> 調音紙對頻響曲線的影響

一、后腔 1.曲線說明 綠色&#xff1a;無調音紙 紅色&#xff1a;使用Y3 粉色&#xff1a;使用Y6 2.結論 后腔是負責微調的&#xff0c;阻尼大小和低頻升降成 反比。 阻 大 -> 低頻 降低 阻 小 -> 低頻 升高 二、前腔 1.曲線說明 紅色&#xff1a;無調音紙 黃色&am…

信息安全與網絡安全---引言

僅供參考 文章目錄 一、計算機安全1.1 CIA三元組1.2 影響等級1.3 計算機安全的挑戰 二、OSI安全體系結構2.1 安全攻擊2.2 安全服務2.3 安全機制 三、基本安全設計準則四、攻擊面和攻擊樹&#xff08;重點&#xff09;4.1 攻擊面4.2 攻擊樹 五、習題與答案 一、計算機安全 &…

C# VB.NET取字符串中全角字符數量和半角字符數量

C# VB.NET中Tuple輕量級數據結構和固定長度數組-CSDN博客 https://blog.csdn.net/xiaoyao961/article/details/148872196 下面提供了三種統計字符串中全角和半角字符數量的方法&#xff0c;并進行了性能對比。 性能對比&#xff08;處理 100 萬次 "Hello&#xff0c;世界…

CC++公司面試題[個人總結,持續更新中]

嵌入式初級面試題 姓名: 日期: 開始時間: (答題時間60分鐘,答題過程中請不要上網查詢資料,不可帶走答卷) 1:設float a=2,b=4,c=3;,以下C語言表達式與代數式(a+b)+c計算結果不一致的是( )[3分] A.(a+b)c/2 B. (1/2)*(a+b)c C. (a+b)c*1/2 D.c/2(a+b) 2:為了向二進制文件尾部…

Qt QGraphics簡述及例程 - QGraphicsView、QGraphicsScene和QGraphicsItem

Qt QGraphics簡述及例程 引言一、簡單例程二、關于坐標系問題 引言 QGraphics*是Qt框架中&#xff0c;主要用于處理2D圖形項的顯示、交互和管理的模塊&#xff0c;包括QGraphicsView、QGraphicsScene和QGraphicsItem。提供了一套高效的場景-視圖架構&#xff0c;適合開發復雜的…

代碼隨想錄打卡第一天

文章講解&#xff1a;代碼隨想錄 視頻講解&#xff1a;手把手帶你撕出正確的二分法 | 二分查找法 | 二分搜索法 | LeetCode&#xff1a;704. 二分查找_嗶哩嗶哩_bilibili class Solution { public:int search(vector<int>& nums, int target) {int left0;//左邊界int…