std::allocator_traits 能做但 std::allocator 不能的事情

🌟 std::allocator_traits 能做但 std::allocator 不能的事情

1?? 適配自定義分配器

假設你要實現一個內存池 MyAllocator,而 STL 容器默認使用的是 std::allocator
如果你希望 STL 容器可以使用你的 MyAllocator,你 不能直接用 std::allocator,但可以通過 std::allocator_traits 讓你的 MyAllocator 兼容 STL。

🚀 代碼示例:
#include <iostream>
#include <memory>
#include <vector>template <typename T>
class MyAllocator {
public:using value_type = T;T* allocate(std::size_t n) {std::cout << "Allocating " << n << " objects\n";return static_cast<T*>(::operator new(n * sizeof(T)));}void deallocate(T* p, std::size_t) {std::cout << "Deallocating objects\n";::operator delete(p);}
};int main() {std::vector<int, MyAllocator<int>> vec;  // 使用自定義分配器vec.push_back(10);  // std::allocator_traits 讓 vec 兼容 MyAllocatorvec.push_back(20);
}

? std::allocator_traits 使 std::vector 兼容 MyAllocator,而 std::allocator 無法做到這一點


2?? rebind 機制:不同類型對象之間的分配

std::allocator 時代,如果你有一個 Allocator<int>,但你想用它來分配 double,你需要手動定義 rebind

template <typename T>
struct MyAllocator {using value_type = T;template <typename U>struct rebind { using other = MyAllocator<U>; };
};

問題:

  • std::allocator<int> 不能直接用于 std::allocator<double>
  • 你必須手動實現 rebind,增加了額外的代碼和復雜度。

解決方案:std::allocator_traits 自動提供 rebind

template <typename T>
class MyAllocator {
public:using value_type = T;T* allocate(std::size_t n) { return static_cast<T*>(::operator new(n * sizeof(T))); }void deallocate(T* p, std::size_t) { ::operator delete(p); }
};int main() {using Alloc = MyAllocator<int>;using ReboundAlloc = std::allocator_traits<Alloc>::rebind_alloc<double>; // 綁定到doubleReboundAlloc alloc; double* p = alloc.allocate(5);  // 現在可以分配 double 了!alloc.deallocate(p, 5);
}

? std::allocator_traits 自動提供 rebind,避免手寫 rebind 邏輯!


3?? constructdestroy 適配自定義指針

std::allocator 時代,construct() 直接調用 new,但是如果你有一個 自定義指針(比如智能指針),你就會發現 std::allocator 無法直接適配。

問題:

  • std::allocator::construct() 只能用于普通指針 T*,不支持 std::unique_ptr<T>std::shared_ptr<T>
  • std::allocator 不支持使用 std::shared_ptr 作為 pointer 類型

解決方案:使用 std::allocator_traits 適配智能指針

#include <iostream>
#include <memory>template <typename T>
struct SmartAllocator {using value_type = T;using pointer = std::unique_ptr<T>; // 使用 unique_ptr 而不是裸指針T* allocate(std::size_t n) {return static_cast<T*>(::operator new(n * sizeof(T)));}void deallocate(T* p, std::size_t) {::operator delete(p);}
};int main() {SmartAllocator<int> alloc;using AllocTraits = std::allocator_traits<SmartAllocator<int>>;int* p = AllocTraits::allocate(alloc, 1);AllocTraits::construct(alloc, p, 42);std::cout << "Constructed value: " << *p << std::endl;AllocTraits::destroy(alloc, p);AllocTraits::deallocate(alloc, p, 1);
}

? std::allocator_traits 使得 SmartAllocator 可以支持 unique_ptr,而 std::allocator 無法支持!


4?? 適配 constexpr 分配器

在現代 C++ 中,某些分配器需要支持 constexpr,而 std::allocator 不能被 constexpr 調用。但 std::allocator_traits 可以提供 constexpr 支持

template <typename T>
struct ConstexprAllocator {using value_type = T;constexpr T* allocate(std::size_t n) {return new T[n];}constexpr void deallocate(T* p, std::size_t) {delete[] p;}
};constexpr int test() {ConstexprAllocator<int> alloc;using AllocTraits = std::allocator_traits<ConstexprAllocator<int>>;int* p = AllocTraits::allocate(alloc, 1);AllocTraits::construct(alloc, p, 42);int val = *p;AllocTraits::destroy(alloc, p);AllocTraits::deallocate(alloc, p, 1);return val;
}static_assert(test() == 42, "Test failed");

? std::allocator_traits 使得 ConstexprAllocator 可以支持 constexpr,而 std::allocator 無法支持!


🎯 總結:std::allocator_traits 相比 std::allocator 的優越性

特性std::allocatorstd::allocator_traits
適配自定義 Allocator? 不支持? 適配 MyAllocator
支持 rebind 機制? 需要手寫 rebind? 自動提供 rebind
支持智能指針? 不支持? 可以適配 unique_ptr
適配 constexpr? 不能 constexpr? 支持 constexpr
統一 STL 分配接口? STL 不能通用? vectormap 都能用

🚀 什么時候必須用 std::allocator_traits

  1. 你在實現自定義 Allocator,并想讓 STL 容器使用它。
  2. 你需要在 Allocator 中使用 unique_ptrshared_ptr
  3. 你想要 Allocator 適用于不同類型的對象(使用 rebind)。
  4. 你希望 Allocatorconstexpr 計算時可以工作。

🔥 結論

雖然 std::allocator 仍然在某些簡單場景下可用,但現代 C++ 開發 幾乎所有 STL 容器 都依賴 std::allocator_traits,而 std::allocator 已經不再直接使用。

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

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

相關文章

QT——c++界面編程庫

非界面編程 QT編譯的時候&#xff0c;依賴于 .pro 配置文件&#xff1a; SOURCES: 所有需要參與編譯的 .cpp 源文件 HEADERS:所有需要參與編譯的.h 頭文件 QT&#xff1a;所有需要參與編譯的 QT函數庫 .pro文件一旦修改&#xff0c;注意需要鍵盤按 ctrls 才能加載最新的配置文…

基于專利合作地址匹配的數據構建區域協同矩陣

文章目錄 地區地址提取完成的處理代碼 在專利合作申請表中&#xff0c;有多家公司合作申請。在專利權人地址中&#xff0c; 有多個公司的地址信息。故想利用這里多個地址。想用這里的地址來代表區域之間的專利合作情況代表區域之間的協同、協作情況。 下圖是專利合作表的一部分…

汽車小助手智能體

汽車小助手&#xff1a;智能驅動汽車服務新體驗 鏈接&#xff1a;文心智能體平臺AgentBuilder | 想象即現實 文心智能體平臺AgentBuilder&#xff0c;是百度推出的基于文心大模型的智能體平臺&#xff0c;支持廣大開發者根據自身行業領域、應用場景&#xff0c;選取不同類型的…

各種傳參形式

一、QueryString 前端請求&#xff1a;http://localhost:8080/test/user/find?id26&namezhangsan 后端接收&#xff1a; 1.參數接收&#xff1a; RequestMapping("/find") public void find(String id,String name){... }2.對象接收&#xff1a; RequestMa…

【vue-echarts】——03.配置項---tooltip

文章目錄 一、tooltip提示框組件二、顯示結果一、tooltip提示框組件 提示框組件,用于配置鼠標滑過或點擊圖表時的顯示框 代碼如下 Demo3View.vue <template><div class="about">

VSCode輕松調試運行.Net 8.0 Web API項目

1.背景 我一直都是用VS來開發.NetCore項目的&#xff0c;用的比較順手&#xff0c;也習慣了。看其他技術文章有介紹VS Code更輕量&#xff0c;更方便。所以我專門花時間來使用VS Code&#xff0c;看看它是如何調試代碼、如何運行.Net 8.0 WebAPI項目。這篇文章是一個記錄的過程…

P8720 [藍橋杯 2020 省 B2] 平面切分--set、pair

P8720 [藍橋杯 2020 省 B2] 平面切分--set、pair 題目 分析一、pair1.1pair與vector的區別1.2 兩者使用場景兩者組合使用 二、set2.1核心特點2.2set的基本操作2.3 set vs unordered_set示例&#xff1a;統計唯一單詞數代碼 題目 分析 大佬寫的很明白&#xff0c;看這兒 我講講…

游戲引擎學習第128天

開始 然而&#xff0c;我們仍然有一些工作要做&#xff0c;渲染部分并沒有完全完成。雖然現在已經能夠運行游戲&#xff0c;而且幀率已經可以接受&#xff0c;但仍然有一些東西需要進一步完善。正在使用調試構建編譯版本&#xff0c;雖然調試版本的性能不如優化版本&#xff0…

多元數據直觀表示(R語言)

一、實驗目的&#xff1a; 通過上機試驗&#xff0c;掌握R語言實施數據預處理及簡單統計分析中的一些基本運算技巧與分析方法&#xff0c;進一步加深對R語言簡單統計分析與圖形展示的理解。 數據&#xff1a; 鏈接: https://pan.baidu.com/s/1kMdUWXuGCfZC06lklO5iXA 提取碼: …

第8天:面向對象編程入門 - 類與對象

第8天&#xff1a;面向對象編程入門 - 類與對象 一、&#x1f4da; 今日學習目標 &#x1f3af; 掌握類與對象的定義與使用&#x1f527; 理解封裝、繼承、多態三大特性&#x1f4a1; 完成銀行賬戶管理系統實戰&#x1f6e0;? 學會構造函數與析構函數的編寫 二、?? 核心知…

Hadoop之02:MapReduce編程模型

MapReduce編程模型 理解MapReduce編程模型獨立完成一個MapReduce程序并運行成功了解MapReduce工程流程掌握并描述出shuffle全過程&#xff08;面試&#xff09;獨立編寫課堂及作業中的MR程序理解并解決數據傾斜 1. MapReduce編程模型 Hadoop架構圖 Hadoop由HDFS分布式存儲、M…

2.7 大模型RAG內容安全合規檢查-大模型ACP模擬題-真題

單選題 在RAG應用中&#xff0c;輸入內容合規檢查的正確順序是&#xff1f; A. 先處理模型生成&#xff0c;后檢查用戶輸入 B. 先檢查用戶輸入&#xff0c;后處理模型生成 ? C. 僅檢查用戶輸入 D. 僅檢查模型輸出 解析&#xff1a;合規流程應優先過濾用戶輸入風險&#xff0…

mapbox基礎,使用geojson加載heatmap熱力圖層

????? 主頁: gis分享者 ????? 感謝各位大佬 點贊?? 收藏? 留言?? 加關注?! ????? 收錄于專欄:mapbox 從入門到精通 文章目錄 一、??前言1.1 ??mapboxgl.Map 地圖對象1.2 ??mapboxgl.Map style屬性1.3 ??heatmap熱力圖層樣式二、??使用geojs…

Deepseek Api Function Calling解析(tools、tool_calls)Deepseek函數調用流程圖、Python代碼示例

文章目錄 Function Calling介紹**核心原理**1. **動態擴展模型能力**2. **JSON結構化交互** **實現步驟**&#xff08;以支持Function Calling的模型為例&#xff09;1. **定義可用函數**2. **模型匹配與生成**3. **開發者執行函數**4. **結果反饋給模型** **DeepSeek R1的當前…

在2023idea中如何創建SpringBoot

目錄 一.下載和安裝 Maven 1.前往 https://maven.apache.org/download.cgi 下載最新版的 Maven 程序 2.將文件解壓到D:Program FilesApachemaven目錄 3.新建環境變量MAVEN_HOME&#xff0c;賦值D:Program FilesApachemaven 4.編輯環境變量Path&#xff0c;追加%MAVEN_HOME…

基于YOLO11深度學習的遙感視角農田檢測與分割系統【python源碼+Pyqt5界面+數據集+訓練代碼】深度學習實戰、目標分割、人工智能

《------往期經典推薦------》 一、AI應用軟件開發實戰專欄【鏈接】 項目名稱項目名稱1.【人臉識別與管理系統開發】2.【車牌識別與自動收費管理系統開發】3.【手勢識別系統開發】4.【人臉面部活體檢測系統開發】5.【圖片風格快速遷移軟件開發】6.【人臉表表情識別系統】7.【…

用冒泡排序法模擬qsort函數

目錄 1.前言 2.qsort函數的介紹 ?3.冒泡法回顧 4.模擬qsort---buble_sort 4.1 buble_sort格式 4.2 主函數&#xff0c;以int類型為例 4.3comp_int函數的功能設計 4.4 swap函數的功能設計 5. 總代碼概覽 1.前言 今天&#xff0c;小鄧兒帶大家用冒泡排序法來模擬一下qs…

全星研發項目管理APQP軟件系統:鑄造芯片集成電路產業研發體系化建設平臺

全星研發項目管理APQP軟件系統&#xff1a;鑄造芯片集成電路產業研發體系化建設平臺 在芯片集成電路行業&#xff0c;研發效率和質量直接決定了企業的核心競爭力。面對日益復雜的芯片設計、日益縮短的產品生命周期以及日益嚴格的質量要求&#xff0c;傳統的研發管理模式已難以滿…

《Python實戰進階》No 11:微服務架構設計與 Python 實現

第11集&#xff1a;微服務架構設計與 Python 實現 2025年3月3日更新了代碼和微服務運行后的系統返回信息截圖&#xff0c;所有代碼在 python3.11.5虛擬環境下運行通過。 微服務架構通過將復雜應用拆分為獨立部署的小型服務&#xff0c;顯著提升了系統的可擴展性和維護性。本集…

USRP7440-通用軟件無線電平臺

1、產品描述 USRP7440基于第三代XILINX Zynq UltraScale RFSoC架構&#xff0c;它將射頻ADC、DAC、ARM、FPGA等集成一體&#xff0c;瞬時帶寬可以達到2.5GHz&#xff0c;尤其適合于射頻直采應用&#xff0c;比如通信與雷達。 第一代RFSOC高達4GHz ? 8x 或 16x 6.554GSPS DAC…