boost::circular_buffer的使用方法简介

boost::circular_buffer:

boost::circular_buffer 是 Boost 库中的一个循环缓冲区容器,特别适用于需要固定容量存储的场景。当缓冲区容量满时,新插入的元素会覆盖最旧或最新的元素(取决于插入方式)。以下是详细的使用方法和示例代码:

1. 基本使用方法

包含头文件
cpp 复制代码
#include <boost/circular_buffer.hpp>
‌‌创建循环缓冲区
cpp 复制代码
boost::circular_buffer<int> cb(3); // 创建容量为3的循环缓冲区
boost::circular_buffer<int> cb2(cb); // 拷贝构造
boost::circular_buffer<int> cb3(std::move(cb)); // 移动构造
‌‌初始化方法

直接指定容量

在构造 boost::circular_buffer 时,直接传入容量参数:

cpp 复制代码
#include <boost/circular_buffer.hpp>
#include <iostream>

int main() {
    // 初始化容量为5的循环缓冲区
    boost::circular_buffer<int> cb(5);

    // 验证容量
    std::cout << "Capacity: " << cb.capacity() << std::endl; // 输出: Capacity: 5
    std::cout << "Size: " << cb.size() << std::endl;         // 输出: Size: 0 (初始为空)

    return 0;
}
  • 初始化时填充默认值

    如果需要初始化时填充默认值,可以结合 std::generate 或循环:

    cpp 复制代码
    #include <boost/circular_buffer.hpp>
    #include <algorithm> // for std::generate
    #include <iostream>
    
    int main() {
        const int capacity = 5;
        boost::circular_buffer<int> cb(capacity);
    
        // 填充默认值0(实际无需显式填充,因为默认构造已初始化)
        std::generate(cb.begin(), cb.end(), []() { return 0; });
    
        // 或者直接通过循环插入
        for (int i = 0; i < capacity; ++i) {
            cb.push_back(0); // 显式插入0
        }
    
        // 验证
        for (const auto& elem : cb) {
            std::cout << elem << " "; // 输出: 0 0 0 0 0
        }
        return 0;
    }

**空间优化版本(circular_buffer_space_optimized)**‌

如果需要动态调整容量以避免内存浪费,可以使用 boost::circular_buffer_space_optimized

cpp 复制代码
#include <boost/circular_buffer_space_optimized.hpp>
#include <iostream>

int main() {
    // 初始最小容量为2,最大容量为10
    boost::circular_buffer_space_optimized<int> cb(2, 10);

    // 插入元素,容量会自动扩展
    for (int i = 0; i < 15; ++i) {
        cb.push_back(i);
        std::cout << "Current capacity: " << cb.capacity() << std::endl;
    }
    // 输出会显示容量从2逐步扩展到10

    return 0;
}

动态调整容量

如果需要后续调整容量,可以使用 set_capacityresize

cpp 复制代码
#include <boost/circular_buffer.hpp>
#include <iostream>

int main() {
    boost::circular_buffer<int> cb(3); // 初始容量3
    cb.push_back(1);
    cb.push_back(2);

    // 动态调整容量为5
    cb.set_capacity(5);
    std::cout << "New capacity: " << cb.capacity() << std::endl; // 输出: 5

    // 继续插入元素(不会覆盖,因为容量扩大)
    cb.push_back(3);
    cb.push_back(4);
    cb.push_back(5);

    // 验证
    for (const auto& elem : cb) {
        std::cout << elem << " "; // 输出: 1 2 3 4 5
    }
    return 0;
}
插入元素
  • ‌**push_back**‌:在尾部插入元素,若缓冲区满,则覆盖最旧的元素(头部)。

  • ‌**push_front** ‌:在头部插入元素,若缓冲区满,则覆盖最新的元素(尾部)。

    cpp 复制代码
    cb.push_back(1); // 插入1
    cb.push_back(2); // 插入2
    cb.push_back(3); // 插入3,此时缓冲区满
    cb.push_back(4); // 覆盖1,缓冲区变为[2, 3, 4]
    
    cb.push_front(5); // 覆盖4,缓冲区变为[5,2,3]
  • ‌**insert** ‌:在指定位置插入元素。

    cpp 复制代码
    auto it = cb.begin() + 1;
    cb.insert(it, 6); // 在第二个位置插入6,缓冲区变为[5,6,2]
访问和遍历元素
  • 通过下标访问 ‌:

    cpp 复制代码
    assert(cb[0] == 2); // 访问第一个元素
    assert(cb.back() == 4); // 访问最后一个元素
  • 通过迭代器遍历 ‌:

    cpp 复制代码
    for (auto it = cb.begin(); it != cb.end(); ++it) {
        std::cout << *it << " "; // 输出:2 3 4
    }
  • 范围循环(推荐) ‌:

    cpp 复制代码
    for (const auto& elem : cb) {
        std::cout << elem << " "; // 输出:2 3 4
    }
移除元素
  • ‌**pop_front**‌:移除最旧的元素(头部)。

  • ‌**pop_back** ‌:移除最新的元素(尾部)。

    cpp 复制代码
    cb.pop_front(); // 移除2,缓冲区变为[3, 4]
    cb.pop_back();  // 移除4,缓冲区变为[3]
  • ‌**erase** ‌:移除指定位置的元素。

    cpp 复制代码
    auto it = cb.begin();
    cb.erase(it); // 移除第一个元素,缓冲区变为空
  • clear:容量不变,仅清空元素。

    cpp 复制代码
    cb.clear()

2. 高级特性函数

容量与状态检查
  • ‌**size** ‌:返回当前元素数量。

    cpp 复制代码
    assert(cb.size() == 3); // 当前元素数量
  • ‌**capacity** ‌:返回缓冲区总容量。

    cpp 复制代码
    assert(cb.capacity() == 3); // 总容量
  • ‌**empty** ‌:检查缓冲区是否为空。

    cpp 复制代码
    if (cb.empty()) { /* 处理空缓冲区 */ }
  • ‌**full** ‌:检查缓冲区是否已满。

    cpp 复制代码
    if (cb.full()) { /* 处理满缓冲区 */ }
‌**旋转缓冲区(rotate)**‌将缓冲区元素旋转指定位置。
cpp 复制代码
cb.rotate(cb.begin() + 1); // 将第二个元素旋转到头部
// 缓冲区从[5,6,2]变为[6,2,5]

‌3**. 完整示例代码**

cpp 复制代码
#include <boost/circular_buffer.hpp>
#include <iostream>
#include <cassert>

int main() {
    // 创建容量为3的循环缓冲区
    boost::circular_buffer<int> cb(3);

    // 插入元素
    cb.push_back(1);
    cb.push_back(2);
    cb.push_back(3);

    // 断言检查
    assert(cb[0] == 1);
    assert(cb[1] == 2);
    assert(cb[2] == 3);
    assert(cb.size() == 3);
    assert(cb.capacity() == 3);

    // 插入新元素(覆盖旧元素)
    cb.push_back(4); // 覆盖1,缓冲区变为[2, 3, 4]
    assert(cb[0] == 2);
    assert(cb[1] == 3);
    assert(cb[2] == 4);

    // 遍历缓冲区
    std::cout << "Buffer contents: ";
    for (const auto& elem : cb) {
        std::cout << elem << " "; // 输出:2 3 4
    }
    std::cout << std::endl;

    // 移除元素
    cb.pop_front(); // 移除2,缓冲区变为[3, 4]
    cb.pop_back();  // 移除4,缓冲区变为[3]

    // 最终状态
    assert(cb.size() == 1);
    assert(cb[0] == 3);

    return 0;
}
cpp 复制代码
#include <boost/circular_buffer.hpp>
#include <iostream>
#include <cassert>

int main() {
    // 创建容量为3的循环缓冲区
    boost::circular_buffer<int> cb(3);

    // 插入元素
    cb.push_back(1);
    cb.push_back(2);
    cb.push_back(3);
    assert(cb.full()); // 缓冲区已满

    // 覆盖插入
    cb.push_back(4); // 覆盖1,缓冲区变为[2,3,4]
    cb.push_front(5); // 覆盖4,缓冲区变为[5,2,3]

    // 遍历缓冲区
    std::cout << "Buffer contents: ";
    for (const auto& elem : cb) {
        std::cout << elem << " "; // 输出:5 2 3
    }
    std::cout << std::endl;

    // 线性化访问
    int* p = cb.linearize();
    assert(p[0] == 5 && p[1] == 2 && p[2] == 3);

    // 旋转缓冲区
    cb.rotate(cb.begin() + 1); // 缓冲区变为[2,3,5]
    for (const auto& elem : cb) {
        std::cout << elem << " "; // 输出:2 3 5
    }

    return 0;
}

‌4**. 关键特性**‌

  1. 固定容量 ‌:与 std::vectorstd::list 不同,boost::circular_buffer 的容量在创建时固定,不会动态增长。
  2. 覆盖策略 ‌:当缓冲区满时,push_back 覆盖头部元素,push_front 覆盖尾部元素。
  3. 高效操作‌:插入和删除操作的时间复杂度为 O(1)。
  4. 线程安全 ‌:若需在多线程环境中使用,需配合互斥锁(如 std::mutex)。
  5. 构造函数初始化 ‌:boost::circular_buffer<int> cb(N) 直接指定容量 N
  6. 动态调整 ‌:使用 set_capacity(N)resize(N, default_value)
  7. 空间优化 ‌:circular_buffer_space_optimized 适合需要动态容量的场景。
  8. 默认值 ‌:Boost 不会自动填充默认值,需手动初始化(如通过 std::generate)。
相关推荐
睡不醒的kun4 小时前
leetcode算法刷题的第三十二天
数据结构·c++·算法·leetcode·职场和发展·贪心算法·动态规划
乔宕一6 小时前
stm32 链接脚本没有 .gcc_except_table 段也能支持 C++ 异常
c++·stm32·嵌入式硬件
SuperCandyXu6 小时前
P3205 [HNOI2010] 合唱队-普及+/提高
c++·算法·洛谷
_君落羽_6 小时前
ARM寄存器以及异常处理
c++
free7 小时前
基于librdkafa C++客户端生产者发送数据失败问题处理#2
c++·kafka
小柯J桑_7 小时前
Linux:线程封装
linux·运维·c++
doll ~CJ8 小时前
基于QVTKOpenGLNativeWidget的三维点云可视化实现
c++·qt·软件开发·三维点云可视化
42fourtytoo9 小时前
天津大学智算2026预推免机试第二批题目及代码c++
开发语言·c++·面试
子豪-中国机器人10 小时前
枚举算法和排序算法能力测试
开发语言·c++·算法