C++ boost::container 详解:高性能容器库完全指南

C++ boost::container 详解:高性能容器库完全指南

  • [一、C++ boost::container 详解](#一、C++ boost::container 详解)
    • [1、 引言:为什么需要 boost::container?](#1、 引言:为什么需要 boost::container?)
    • [2、 boost::container 核心容器详解](#2、 boost::container 核心容器详解)
      • [2.1 、序列容器(Sequence Containers)](#2.1 、序列容器(Sequence Containers))
        • [2.1.1 、vector 的增强版:`boost::container::vector`](#2.1.1 、vector 的增强版:boost::container::vector)
        • [2.1.2、 静态大小向量:`boost::container::static_vector`](#2.1.2、 静态大小向量:boost::container::static_vector)
        • [2.1.3、 稳定向量:`boost::container::stable_vector`](#2.1.3、 稳定向量:boost::container::stable_vector)
      • [2.2 、关联容器(Associative Containers)](#2.2 、关联容器(Associative Containers))
        • [2.2.1 、平面映射:`boost::container::flat_map`](#2.2.1 、平面映射:boost::container::flat_map)
        • [2.2.2 、节点映射:`boost::container::map`](#2.2.2 、节点映射:boost::container::map)
      • [2.3 、无序容器(Unordered Containers)](#2.3 、无序容器(Unordered Containers))
    • 3、高级特性与配置
      • [3.1、 自定义分配器(Allocators)](#3.1、 自定义分配器(Allocators))
      • [3.2、 异常安全配置](#3.2、 异常安全配置)
      • [3.3、 移动语义优化](#3.3、 移动语义优化)
    • [4、 性能优化实践](#4、 性能优化实践)
      • [4.1 、内存池优化](#4.1 、内存池优化)
      • [4.2 、小对象优化](#4.2 、小对象优化)
      • [4.3、 预分配与重用](#4.3、 预分配与重用)
    • [5、 实际应用案例](#5、 实际应用案例)
      • [5.1 、高性能缓存实现](#5.1 、高性能缓存实现)
      • [5.2 、实时系统数据收集](#5.2 、实时系统数据收集)
  • 二、boost库使用步骤
  • 三、代码示例

一、C++ boost::container 详解

1、 引言:为什么需要 boost::container?

在 C++ 标准库(STL)已经提供了 std::vectorstd::mapstd::set 等丰富容器的情况下,为什么还需要 boost::container?答案在于 性能、灵活性和高级特性

boost::container 是 Boost 库中的一个重要组件,它提供了 STL 容器的替代实现,具有以下核心优势:

  • 更优的内存控制:支持自定义分配器、小缓冲区优化(SBO)、节点池等
  • 更丰富的配置选项:可配置的异常安全保证、移动语义优化
  • 扩展的容器类型 :提供 flat_mapstable_vectorstatic_vector 等 STL 没有的容器
  • 更好的多线程支持:线程安全的分配器选项
  • 与 STL 的高度兼容:API 与 STL 容器基本一致,迁移成本低

2、 boost::container 核心容器详解

2.1 、序列容器(Sequence Containers)

2.1.1 、vector 的增强版:boost::container::vector
cpp 复制代码
#include <boost/container/vector.hpp>
#include <boost/container/small_vector.hpp>
#include <iostream>

int main() {
    // 1. 普通 boost vector
    boost::container::vector<int> vec = { 1, 2, 3, 4, 5 };

    vec.reserve(100);    // 预分配内存
    vec.resize(100);     // 初始化元素
    vec.clear();         // 清空
    vec.shrink_to_fit(); // 释放多余内存


    // ========================
    // 2. small_vector(栈上优化)
    // ========================
    boost::container::small_vector<int, 10> sbo_vec;

    // 插入 10 个元素(全部在栈上)
    for (int i = 0; i < 10; ++i)
        sbo_vec.push_back(i);

    std::cout << "size:  " << sbo_vec.size() << "\n";
    std::cout << "capacity: " << sbo_vec.capacity() << "\n";

    // 插入第 11 个 → 自动移到堆
    sbo_vec.push_back(100);

    // 遍历
    std::cout << "\n遍历:";
    for (int v : sbo_vec)
        std::cout << v << " ";
    std::cout << "\n";

    return 0;
}
2.1.2、 静态大小向量:boost::container::static_vector
cpp 复制代码
#include <boost/container/static_vector.hpp>

void static_vector_demo() {
    // 模板参数:最大容量,编译时确定
    boost::container::static_vector<int, 10> static_vec;
    
    // 栈上分配,无堆内存分配
    static_vec.push_back(1);
    static_vec.push_back(2);
    
    // 容量固定,不能超过10个元素
    // static_vec.push_back(11);  // 运行时错误:超出容量
    
    // 适用于嵌入式系统、实时系统
    // 避免动态内存分配的开销和碎片
}
2.1.3、 稳定向量:boost::container::stable_vector
cpp 复制代码
#include <boost/container/stable_vector.hpp>

void stable_vector_demo() {
    boost::container::stable_vector<int> stable_vec;
    
    // 插入元素
    auto it1 = stable_vec.insert(stable_vec.end(), 100);
    auto it2 = stable_vec.insert(stable_vec.end(), 200);
    
    // 关键特性:迭代器和引用永久有效
    // 即使插入/删除其他元素,it1 和 it2 仍然有效
    stable_vec.insert(stable_vec.begin(), 50);
    
    std::cout << *it1 << std::endl;  // 仍然输出 100
    std::cout << *it2 << std::endl;  // 仍然输出 200
    
    // 应用场景:需要长期保持迭代器/引用的算法
}

2.2 、关联容器(Associative Containers)

2.2.1 、平面映射:boost::container::flat_map
cpp 复制代码
#include <boost/container/flat_map.hpp>
#include <algorithm>

void flat_map_demo() {
    // flat_map 底层使用排序的 vector 存储键值对
    boost::container::flat_map<std::string, int> flat_map;
    
    // 插入元素
    flat_map.insert({"apple", 5});
    flat_map.insert({"banana", 3});
    flat_map.insert({"orange", 8});
    
    // 自动按键排序
    for (const auto& [key, value] : flat_map) {
        std::cout << key << ": " << value << std::endl;
    }
    
    // 性能特点:
    // 优点:内存局部性好,缓存友好,内存占用小
    // 缺点:插入/删除 O(n),查找 O(log n)
    
    // 适用场景:读多写少,数据量不大
}
2.2.2 、节点映射:boost::container::map
cpp 复制代码
#include <boost/container/map.hpp>

void boost_map_demo() {
    // 与 std::map 类似,但提供更多配置选项
    boost::container::map<std::string, int> map;
    
    // 支持自定义分配器
    using Allocator = boost::container::new_allocator<std::pair<const std::string, int>>;
    boost::container::map<std::string, int, std::less<>, Allocator> custom_map;
    
    // 支持节点句柄(C++17 特性在 Boost 中的实现)
    auto node = map.extract("key");
    if (!node.empty()) {
        custom_map.insert(std::move(node));
    }
}

2.3 、无序容器(Unordered Containers)

cpp 复制代码
#include <boost/container/unordered_map.hpp>
#include <boost/container/unordered_set.hpp>

void unordered_containers_demo() {
    // unordered_map 增强版
    boost::container::unordered_map<std::string, int> umap;
    
    // 配置桶的数量和最大负载因子
    umap.rehash(100);  // 预分配100个桶
    umap.max_load_factor(0.75f);  // 设置最大负载因子
    
    // unordered_set
    boost::container::unordered_set<int> uset = {1, 2, 3, 4, 5};
    
    // 支持自定义哈希和相等比较器
    struct StringHash {
        std::size_t operator()(const std::string& s) const {
            return std::hash<std::string>{}(s);
        }
    };
    
    boost::container::unordered_set<std::string, StringHash> custom_uset;
}

3、高级特性与配置

3.1、 自定义分配器(Allocators)

cpp 复制代码
#include <boost/container/allocator.hpp>
#include <boost/container/pmr/polymorphic_allocator.hpp>

// 1. 使用 Boost 提供的分配器
void allocator_demo() {
    // 使用 new/delete 的分配器
    boost::container::allocator<int> alloc1;
    
    // 线程安全的分配器
    boost::container::thread_safe_allocator<int> alloc2;
    
    // 小缓冲区优化分配器
    boost::container::small_vector_allocator<int, 16> alloc3;
}

// 2. 自定义分配器
template<typename T>
class MyAllocator {
public:
    using value_type = T;
    
    MyAllocator() = default;
    
    template<typename U>
    MyAllocator(const MyAllocator<U>&) {}
    
    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);
    }
};

void custom_allocator_demo() {
    boost::container::vector<int, MyAllocator<int>> vec;
    vec.push_back(42);
}

3.2、 异常安全配置

cpp 复制代码
#include <boost/container/vector.hpp>
#include <boost/container/throw_exception.hpp>

void exception_safety_demo() {
    // 配置容器的异常安全保证
    using NoThrowVector = boost::container::vector<
        int, 
        boost::container::new_allocator<int>,
        boost::container::throw_exception_policy  // 抛出异常
    >;
    
    using NoThrowVector2 = boost::container::vector<
        int,
        boost::container::new_allocator<int>,
        boost::container::no_throw_policy  // 不抛出异常,返回错误码
    >;
    
    NoThrowVector vec;
    try {
        vec.reserve(1000000000000ULL);  // 可能抛出 std::bad_alloc
    } catch (const std::bad_alloc& e) {
        std::cerr << "内存分配失败: " << e.what() << std::endl;
    }
}

3.3、 移动语义优化

cpp 复制代码
#include <boost/container/vector.hpp>
#include <boost/move/utility.hpp>

class MoveOnlyType {
    BOOST_MOVABLE_BUT_NOT_COPYABLE(MoveOnlyType)
    int* data;
    
public:
    MoveOnlyType() : data(new int(0)) {}
    
    // 移动构造函数
    MoveOnlyType(BOOST_RV_REF(MoveOnlyType) other) : data(other.data) {
        other.data = nullptr;
    }
    
    // 移动赋值运算符
    MoveOnlyType& operator=(BOOST_RV_REF(MoveOnlyType) other) {
        if (this != &other) {
            delete data;
            data = other.data;
            other.data = nullptr;
        }
        return *this;
    }
    
    ~MoveOnlyType() { delete data; }
};

void move_semantics_demo() {
    boost::container::vector<MoveOnlyType> vec;
    
    MoveOnlyType obj1;
    vec.push_back(boost::move(obj1));  // 使用移动语义
    
    // 容器内部也使用移动语义优化
    vec.reserve(100);
    // 重新分配时,元素会被移动而不是复制
}

4、 性能优化实践

4.1 、内存池优化

cpp 复制代码
#include <boost/container/vector.hpp>
#include <boost/pool/pool_alloc.hpp>

void memory_pool_demo() {
    // 使用 Boost.Pool 作为分配器
    using PoolAlloc = boost::fast_pool_allocator<int>;
    boost::container::vector<int, PoolAlloc> vec;
    
    // 批量插入大量数据
    for (int i = 0; i < 1000000; ++i) {
        vec.push_back(i);
    }
    
    // 优点:
    // 1. 减少内存碎片
    // 2. 提高分配/释放速度
    // 3. 更好的缓存局部性
    
    // 适用场景:频繁分配/释放大量小对象
}

4.2 、小对象优化

cpp 复制代码
#include <boost/container/small_vector.hpp>

void small_object_optimization() {
    // small_vector:结合 vector 和 static_vector 的优点
    boost::container::small_vector<int, 16> small_vec;
    
    // 前16个元素分配在栈上
    for (int i = 0; i < 10; ++i) {
        small_vec.push_back(i);  // 栈分配,无堆操作
    }
    
    // 超过容量后自动切换到堆
    for (int i = 0; i < 20; ++i) {
        small_vec.push_back(i);  // 后4个元素在堆上
    }
    
    // 性能优势:
    // 1. 减少堆分配次数
    // 2. 更好的缓存局部性
    // 3. 避免内存碎片
}

4.3、 预分配与重用

cpp 复制代码
#include <boost/container/vector.hpp>
#include <boost/container/list.hpp>

void preallocation_demo() {
    // 1. 预分配内存
    boost::container::vector<int> vec;
    vec.reserve(1000);  // 一次性分配足够内存
    
    // 2. 重用容器(避免反复分配)
    boost::container::list<int> reusable_list;
    
    auto reuse_container = [&reusable_list](const auto& data) {
        reusable_list.clear();  // 清空内容,保留内存
        for (const auto& item : data) {
            reusable_list.push_back(item);
        }
        // 处理 reusable_list...
    };
    
    // 3. 使用 node_handle 转移节点
    boost::container::map<int, std::string> map1, map2;
    map1[1] = "one";
    
    auto node = map1.extract(1);
    if (!node.empty()) {
        map2.insert(std::move(node));  // 节点转移,无内存分配
    }
}

5、 实际应用案例

5.1 、高性能缓存实现

cpp 复制代码
#include <boost/container/flat_map.hpp>
#include <boost/container/static_vector.hpp>
#include <chrono>
#include <string>

class LRUCache {
private:
    struct CacheEntry {
        std::string key;
        std::string value;
        std::chrono::steady_clock::time_point timestamp;
        
        bool operator<(const CacheEntry& other) const {
            return timestamp < other.timestamp;
        }
    };
    
    // 使用 flat_map 提高查找性能
    boost::container::flat_map<std::string, CacheEntry> cache_map;
    
    // 使用 static_vector 限制缓存大小
    static constexpr size_t MAX_SIZE = 1000;
    boost::container::static_vector<CacheEntry*, MAX_SIZE> lru_list;
    
public:
    std::string get(const std::string& key) {
        auto it = cache_map.find(key);
        if (it == cache_map.end()) {
            return "";
        }
        
        // 更新访问时间
        it->second.timestamp = std::chrono::steady_clock::now();
        return it->second.value;
    }
    
    void put(const std::string& key, const std::string& value) {
        if (cache_map.size() >= MAX_SIZE) {
            // 移除最久未使用的
            std::sort(lru_list.begin(), lru_list.end(),
                     [](const auto* a, const auto* b) {
                         return *a < *b;
                     });
            cache_map.erase(lru_list.front()->key);
            lru_list.erase(lru_list.begin());
        }
        
        CacheEntry entry{key, value, std::chrono::steady_clock::now()};
        cache_map[key] = entry;
        lru_list.push_back(&cache_map[key]);
    }
};

5.2 、实时系统数据收集

cpp 复制代码
#include <boost/container/static_vector.hpp>
#include <boost/container/stable_vector.hpp>
#include <atomic>
#include <thread>

class RealTimeDataCollector {
private:
    // 使用 static_vector 避免动态内存分配
    boost::container::static_vector<double, 1024> sensor_data;
    
    // 使用 stable_vector 保持迭代器有效性
    boost::container::stable_vector<std::thread::id> thread_ids;
    
    std::atomic<bool> collecting{false};
    
public:
    void start_collection() {
        collecting = true;
        sensor_data.clear();
        thread_ids.clear();
    }
    
    void add_data(double value, std::thread::id tid) {
        if (!collecting) return;
        
        // 快速插入,无内存分配
        sensor_data.push_back(value);
        
        // 记录线程ID,迭代器保持有效
        auto it = thread_ids.insert(thread_ids.end(), tid);
        
        // 可以安全存储迭代器供后续使用
        store_iterator(it);
    }
    
    void stop_collection() {
        collecting = false;
        
        // 处理收集的数据
        process_data(sensor_data.begin(), sensor_data.end());
        process_threads(thread_ids.begin(), thread_ids.end());
    }
    
private:
    void store_iterator(boost::container::stable_vector<std::thread::id>::iterator it) {
        // 即使插入新元素,it 仍然有效
    }
    
    void process_data(auto begin, auto end) {
        // 处理传感器数据
    }
    
    void process_threads(auto begin, auto end) {
        // 处理线程信息
    }
};

二、boost库使用步骤

1、下载库

访问链接https://www.boost.org/

2、Visual Studio新建工程

3、将源码解压到工程目录下

新建一个main.cpp文件

将下载的压缩包解压到main.cpp同级目录,并改名为boost

4、添加路径

三、代码示例

1、测试代码

cpp 复制代码
#include <iostream>
#include <string>
#include <algorithm>

// Boost容器头文件
#include <boost/container/vector.hpp>
#include <boost/container/static_vector.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/container/flat_set.hpp>
#include <boost/container/list.hpp>
#include <boost/container/deque.hpp>
#include <boost/container/string.hpp>

namespace bc = boost::container;

// 自定义测试结构体
struct Person
{
    int id;
    std::string name;
    bool operator<(const Person& other) const
    {
        return id < other.id;
    }
};

int main()
{
    // ===================== 1. bc::vector 动态数组 =====================
    std::cout << "===== boost::container::vector =====\n";
    bc::vector<int> vec{ 1, 3, 5, 7, 9 };
    vec.push_back(11);
    vec.emplace_back(13);

    // 遍历
    for (auto val : vec) std::cout << val << " ";
    std::cout << "\nsize:" << vec.size() << " capacity:" << vec.capacity() << "\n";

    // 排序
    std::sort(vec.begin(), vec.end());

    // ===================== 2. static_vector 栈内存数组 =====================
    std::cout << "\n===== boost::container::static_vector =====\n";
    bc::static_vector<double, 6> st_vec; // 栈分配,最大容纳6个元素
    st_vec.insert(st_vec.end(), { 1.1, 2.2, 3.3 });
    st_vec.pop_back();

    for (auto v : st_vec) std::cout << v << " ";
    std::cout << "\nsize:" << st_vec.size() << " max_size:" << st_vec.max_size() << "\n";

    // ===================== 3. flat_map 高性能有序映射 =====================
    std::cout << "\n===== boost::container::flat_map =====\n";
    bc::flat_map<int, std::string> f_map;
    f_map[101] = "技术部";
    f_map[102] = "市场部";
    f_map[103] = "研发部";

    // 查找
    auto iter = f_map.find(102);
    if (iter != f_map.end())
        std::cout << "102对应部门:" << iter->second << "\n";

    // 遍历
    for (auto& p : f_map)
        std::cout << p.first << " -> " << p.second << "\n";

    // ===================== 4. flat_set 高性能有序集合 =====================
    std::cout << "\n===== boost::container::flat_set =====\n";
    bc::flat_set<Person> f_set;
    f_set.insert({ 1, "小明" });
    f_set.insert({ 2, "小红" });
    f_set.insert({ 1, "小明" }); // 自动去重

    for (auto& p : f_set)
        std::cout << p.id << ":" << p.name << " ";
    std::cout << "\n";

    // ===================== 5. list 双向链表 =====================
    std::cout << "\n===== boost::container::list =====\n";
    bc::list<std::string> str_list{ "apple", "banana", "orange" };
    str_list.push_front("grape");
    str_list.remove("banana");

    for (auto& s : str_list) std::cout << s << " ";
    std::cout << "\n";

    // ===================== 6. deque 双端队列 =====================
    std::cout << "\n===== boost::container::deque =====\n";
    bc::deque<int> dq;
    dq.push_front(10);
    dq.push_back(20);
    dq.push_front(5);

    while (!dq.empty())
    {
        std::cout << dq.front() << " ";
        dq.pop_front();
    }
    std::cout << "\n";

    // ===================== 7. boost自定义string =====================
    std::cout << "\n===== boost::container::string =====\n";
    bc::string b_str("Boost Container Test");
    b_str += " String";
    std::cout << b_str << "\n";

    return 0;
}

2、运行结果

cpp 复制代码
===== boost::container::vector =====
1 3 5 7 9 11 13
size:7 capacity:8

===== boost::container::static_vector =====
1.1 2.2
size:2 max_size:6

===== boost::container::flat_map =====
102对应部门:市场部
101 -> 技术部
102 -> 市场部
103 -> 研发部

===== boost::container::flat_set =====
1:小明 2:小红

===== boost::container::list =====
grape apple orange

===== boost::container::deque =====
5 10 20

===== boost::container::string =====
Boost Container Test String

C:\Users\徐鹏\Desktop\新建文件夹\Project2\x64\Debug\Project2.exe (进程 3232)已退出,代码为 0 (0x0)。
要在调试停止时自动关闭控制台,请启用"工具"->"选项"->"调试"->"调试停止时自动关闭控制台"。
按任意键关闭此窗口. . .
相关推荐
Y_Bk1 小时前
第十七届蓝桥杯C/C++A组省赛
c语言·数据结构·c++·算法·蓝桥杯
Brilliantwxx1 小时前
【C++】 C++11 知识点梳理(上)
开发语言·c++
飞天狗1111 小时前
零基础JavaWeb入门——第4课:表单处理 —— 浏览器怎么把数据发给服务器
java·开发语言·前端·后端·servlet
多彩电脑1 小时前
向AIDE(安卓设备上的Android Studio)导入aar库
android·java·开发语言·androidx
江屿风2 小时前
C++图论基础单源最短路-常规版dijkstra算法/堆优化版dijkstra算法/bellman-ford 算法/spfa 算法流食般投喂
开发语言·c++·笔记·算法·图论
摇滚侠2 小时前
MyBatis 入门到项目实战 MyBatis 逆向工程 62
java·开发语言·mybatis
ch.ju2 小时前
Java Programming Chapter 4——Multi-level inheritance
java·开发语言
Molesidy2 小时前
【Linux】【C++】Linux下的C++编程以及基于GDB的VSCode的C++调试
开发语言·c++
techdashen2 小时前
用 Rust 真正发出 Ping:FFI 类型、newtype 与 MaybeUninit
开发语言·后端·rust