boost::circular_buffer:
boost::circular_buffer
是 Boost 库中的一个循环缓冲区容器,特别适用于需要固定容量存储的场景。当缓冲区容量满时,新插入的元素会覆盖最旧或最新的元素(取决于插入方式)。以下是详细的使用方法和示例代码:
1. 基本使用方法
包含头文件
#include <boost/circular_buffer.hpp>
创建循环缓冲区
boost::circular_buffer<int> cb(3); // 创建容量为3的循环缓冲区 boost::circular_buffer<int> cb2(cb); // 拷贝构造 boost::circular_buffer<int> cb3(std::move(cb)); // 移动构造
初始化方法
直接指定容量
在构造
boost::circular_buffer
时,直接传入容量参数:#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
或循环:#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
:#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_capacity
或resize
:#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
:在头部插入元素,若缓冲区满,则覆盖最新的元素(尾部)。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
:在指定位置插入元素。auto it = cb.begin() + 1; cb.insert(it, 6); // 在第二个位置插入6,缓冲区变为[5,6,2]
访问和遍历元素
- 通过下标访问:
assert(cb[0] == 2); // 访问第一个元素 assert(cb.back() == 4); // 访问最后一个元素
- 通过迭代器遍历:
for (auto it = cb.begin(); it != cb.end(); ++it) { std::cout << *it << " "; // 输出:2 3 4 }
- 范围循环(推荐):
for (const auto& elem : cb) { std::cout << elem << " "; // 输出:2 3 4 }
移除元素
-
pop_front
:移除最旧的元素(头部)。-
pop_back
:移除最新的元素(尾部)。cb.pop_front(); // 移除2,缓冲区变为[3, 4] cb.pop_back(); // 移除4,缓冲区变为[3]
-
erase
:移除指定位置的元素。auto it = cb.begin(); cb.erase(it); // 移除第一个元素,缓冲区变为空
clear:
容量不变,仅清空元素。cb.clear()
2. 高级特性函数
容量与状态检查
-
size
:返回当前元素数量。assert(cb.size() == 3); // 当前元素数量
-
capacity
:返回缓冲区总容量。assert(cb.capacity() == 3); // 总容量
-
empty
:检查缓冲区是否为空。if (cb.empty()) { /* 处理空缓冲区 */ }
-
full
:检查缓冲区是否已满。if (cb.full()) { /* 处理满缓冲区 */ }
旋转缓冲区(
rotate
)将缓冲区元素旋转指定位置。cb.rotate(cb.begin() + 1); // 将第二个元素旋转到头部 // 缓冲区从[5,6,2]变为[6,2,5]
3. 完整示例代码
#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; }
#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. 关键特性
- 固定容量:与
std::vector
或std::list
不同,boost::circular_buffer
的容量在创建时固定,不会动态增长。- 覆盖策略:当缓冲区满时,
push_back
覆盖头部元素,push_front
覆盖尾部元素。- 高效操作:插入和删除操作的时间复杂度为 O(1)。
- 线程安全:若需在多线程环境中使用,需配合互斥锁(如
std::mutex
)。- 构造函数初始化:
boost::circular_buffer<int> cb(N)
直接指定容量N
。- 动态调整:使用
set_capacity(N)
或resize(N, default_value)
。- 空间优化:
circular_buffer_space_optimized
适合需要动态容量的场景。- 默认值:Boost 不会自动填充默认值,需手动初始化(如通过
std::generate
)。