Useful Boost Libraries
基于 boost 1.82…
timer 计时器
过去老的 boost/timer.hpp 已经废弃了,目前推荐使用的是 boost/timer/timer.hpp, 主要包括下面了2个类
| class | detail |
|---|---|
boost::timer::cpu_timer | 计时器 |
boost::timer::auto_cpu_timer | 计时器,基于cpu_timer实现,在析构的时候输出耗时 |
struct cpu_times {
nanosecond_type wall; // 挂钟时间
nanosecond_type user; // 用户时间
nanosecond_type system; // 系统时间
void clear() {wall = user = system = 0LL; }
};默认的输出格式为下:
“%w s wall, %u s user + %s s system = %t s CPU (%p%)\n”
| format | meaning |
|---|---|
| %w | times.wall |
| %u | times.user |
| %s | times.system |
| %t | times.user + times.system |
| %p | The percentage of times.wall represented by times.user + times.system |
来个简单的例子:
#include <boost/timer/timer.hpp>
#include <cmath>
#include <iostream>
using namespace std;
using namespace boost;
int main() {
timer::cpu_timer t;
timer::auto_cpu_timer auto_timer(6, "%ws real time\n");
for (long i = 0; i < 100000000; ++i)
auto _ = sqrt(i * i); // spend some time
cout << t.format(2, "%us user + %ss system = %ts(%p%)") << endl;
t.start();
for (long i = 0; i < 100000000; ++i)
auto _ = sqrt(i * i); // spend some time
cout << t.format(2, "%us user + %ss system = %ts(%p%)") << endl;
return 0;
}split
头文件为 boost/algorithm/string/split.hpp
#include <boost/algorithm/string.hpp>
#include <iostream>
#include <string>
#include <set>
int main(int argc, char *argv[]) {
std::string str = "123,,345,qwe;adq,345";
std::set<std::string> st;
boost::split(st, str, boost::is_any_of(",; "), boost::token_compress_on);
for_each(st.begin(), st.end(), [](const std::string& x) {std::cout << "[" << x << "]\n";});
return 0;
}默认为 token_compress_off: 表示遇见多个token时候,不合并成一个token, 这时候,,分割后,会多一个空string,表示2个逗号中间的空string
需要链接的库: libboost_system (通常自动链接)
circular_buffer 环形缓冲区
Boost.Circular_buffer 提供了固定大小的环形缓冲区,当缓冲区满时自动覆盖最旧的数据。C++23 标准库中没有类似功能。
头文件: boost/circular_buffer.hpp
#include <boost/circular_buffer.hpp>
#include <iostream>
int main() {
// 创建容量为 5 的环形缓冲区
boost::circular_buffer<int> cb(5);
// 添加元素
for (int i = 0; i < 7; ++i) {
cb.push_back(i);
std::cout << "Added " << i << ", size: " << cb.size()
<< ", capacity: " << cb.capacity() << "\n";
}
// 输出内容
std::cout << "Contents: ";
for (const auto& item : cb) {
std::cout << item << " ";
}
std::cout << "\n";
// 访问元素
std::cout << "Front: " << cb.front() << "\n";
std::cout << "Back: " << cb.back() << "\n";
std::cout << "cb[2]: " << cb[2] << "\n";
// 插入到指定位置
cb.insert(cb.begin() + 2, 99);
std::cout << "After insert: ";
for (const auto& item : cb) {
std::cout << item << " ";
}
std::cout << "\n";
// 弹出元素
cb.pop_front();
std::cout << "After pop_front: ";
for (const auto& item : cb) {
std::cout << item << " ";
}
std::cout << "\n";
return 0;
}需要链接的库: header-only
heap 优先队列
Boost.Heap 提供了多种优先队列实现,包括二叉堆、斐波那契堆等。C++23 只有 std::priority_queue,功能有限。
头文件: boost/heap/priority_queue.hpp
#include <boost/heap/priority_queue.hpp>
#include <iostream>
#include <string>
int main() {
// 使用 priority_queue(二叉堆)
boost::heap::priority_queue<int> pq;
// 插入元素
pq.push(5);
pq.push(3);
pq.push(8);
pq.push(1);
pq.push(4);
std::cout << "Priority queue size: " << pq.size() << "\n";
std::cout << "Top element: " << pq.top() << "\n";
// 弹出元素
while (!pq.empty()) {
std::cout << "Pop: " << pq.top() << "\n";
pq.pop();
}
// 使用自定义比较器
auto cmp = [](const std::string& a, const std::string& b) {
return a.length() < b.length(); // 按长度排序
};
boost::heap::priority_queue<std::string, boost::heap::compare<decltype(cmp)>>
strPq(cmp);
strPq.push("hello");
strPq.push("hi");
strPq.push("hey there");
strPq.push("a");
std::cout << "\nString priority queue (by length):\n";
while (!strPq.empty()) {
std::cout << "Pop: " << strPq.top() << "\n";
strPq.pop();
}
// 使用 fibonacci_heap(更好的合并性能)
boost::heap::fibonacci_heap<int> fibHeap;
fibHeap.push(10);
fibHeap.push(20);
fibHeap.push(5);
std::cout << "\nFibonacci heap top: " << fibHeap.top() << "\n";
return 0;
}需要链接的库: header-only
string_algo 字符串算法
Boost.String_algo 提供了丰富的字符串处理算法,比 STL 的字符串操作更强大。
头文件: boost/algorithm/string.hpp
#include <boost/algorithm/string.hpp>
#include <iostream>
#include <string>
#include <vector>
int main() {
std::string text = " Hello, World! ";
// 大小写转换
std::string upper = boost::to_upper_copy(text);
std::string lower = boost::to_lower_copy(text);
std::cout << "Upper: " << upper << "\n";
std::cout << "Lower: " << lower << "\n";
// 去除空白
std::string trimmed = boost::trim_copy(text);
std::cout << "Trimmed: " << trimmed << "\n";
// 查找和替换
std::string replaced = boost::replace_all_copy(text, "World", "Boost");
std::cout << "Replaced: " << replaced << "\n";
// 查找子串
if (boost::contains(text, "Hello")) {
std::cout << "Contains 'Hello'\n";
}
// 检查前缀和后缀
if (boost::starts_with(text, " ")) {
std::cout << "Starts with spaces\n";
}
if (boost::ends_with(text, " ")) {
std::cout << "Ends with spaces\n";
}
// 分割字符串
std::string data = "apple,banana,orange";
std::vector<std::string> fruits;
boost::split(fruits, data, boost::is_any_of(","));
std::cout << "Fruits:\n";
for (const auto& fruit : fruits) {
std::cout << " " << fruit << "\n";
}
// 连接字符串
std::string joined = boost::join(fruits, ";");
std::cout << "Joined: " << joined << "\n";
// 删除字符
std::string removed = boost::erase_all_copy(text, " ");
std::cout << "Removed spaces: " << removed << "\n";
// 查找第N个位置
std::string str = "a-b-c-d-e";
size_t pos = boost::find_nth(str, "-", 2).begin() - str.begin();
std::cout << "3rd '-' at position: " << pos << "\n";
// 查找所有匹配
std::vector<boost::iterator_range<std::string::iterator>> matches;
boost::find_all(matches, str, "-");
std::cout << "Found " << matches.size() << " '-' characters\n";
return 0;
}需要链接的库: header-only
tokenizer 字符串分词器
Boost.Tokenizer 提供了灵活的字符串分词功能,支持多种分词策略。
头文件: boost/tokenizer.hpp
#include <boost/tokenizer.hpp>
#include <iostream>
#include <string>
int main() {
// 使用字符分隔符
std::string str1 = "Hello,World,Boost,C++";
boost::char_separator<char> sep(",");
boost::tokenizer<boost::char_separator<char>> tokens1(str1, sep);
std::cout << "Character separator:\n";
for (const auto& token : tokens1) {
std::cout << " " << token << "\n";
}
// 使用空格分隔(跳过连续空格)
std::string str2 = "Hello World Boost";
boost::char_separator<char> space_sep(" ", "", boost::drop_empty_tokens);
boost::tokenizer<boost::char_separator<char>> tokens2(str2, space_sep);
std::cout << "\nSpace separator (drop empty):\n";
for (const auto& token : tokens2) {
std::cout << " " << token << "\n";
}
// 使用 escaped_list_separator(类似 CSV)
std::string str3 = "1,\"Hello, World\",3.14";
boost::escaped_list_separator<char> els("\\", ",", "\"");
boost::tokenizer<boost::escaped_list_separator<char>> tokens3(str3, els);
std::cout << "\nEscaped list separator (CSV-like):\n";
for (const auto& token : tokens3) {
std::cout << " " << token << "\n";
}
// 使用 offset_separator(固定宽度)
std::string str4 = "1234567890";
int offsets[] = {3, 3, 4};
boost::offset_separator off_sep(offsets, offsets + 3);
boost::tokenizer<boost::offset_separator> tokens4(str4, off_sep);
std::cout << "\nOffset separator (fixed width):\n";
for (const auto& token : tokens4) {
std::cout << " " << token << "\n";
}
return 0;
}需要链接的库: header-only
lockfree 无锁数据结构
Boost.Lockfree 提供了无锁队列、栈等数据结构,用于高并发场景。C++23 标准库中没有类似功能。
头文件: boost/lockfree/queue.hpp
#include <boost/lockfree/queue.hpp>
#include <boost/lockfree/stack.hpp>
#include <iostream>
#include <thread>
#include <vector>
int main() {
// 无锁队列
boost::lockfree::queue<int> q(100); // 固定大小
// 生产者线程
auto producer = [&]() {
for (int i = 0; i < 1000; ++i) {
while (!q.push(i)) {
// 队列满,重试
}
}
};
// 消费者线程
std::atomic<int> sum{0};
auto consumer = [&]() {
int value;
while (true) {
if (q.pop(value)) {
sum += value;
} else {
// 队列空,检查是否完成
if (sum.load() >= 499500) { // 0+1+...+999 = 499500
break;
}
}
}
};
std::thread t1(producer);
std::thread t2(consumer);
t1.join();
t2.join();
std::cout << "Sum: " << sum << "\n";
// 无锁栈
boost::lockfree::stack<int> s(100);
for (int i = 0; i < 10; ++i) {
s.push(i);
}
std::cout << "Stack contents:\n";
int value;
while (s.pop(value)) {
std::cout << value << " ";
}
std::cout << "\n";
return 0;
}需要链接的库: header-only
pool 内存池
Boost.Pool 提供了高性能的内存池实现,适用于频繁分配/释放小对象的场景。
与 jemalloc/tcmalloc 的关系
你可能会问:”有了 jemalloc/tcmalloc 这类高性能 malloc,还需要 Boost.Pool 吗?”
答案是:jemalloc 解决的是通用内存分配问题,Pool 解决的是对象池语义问题。二者不在同一层面:
| 特性 | jemalloc/tcmalloc | Boost.Pool |
|---|---|---|
| 层级 | 系统级 malloc 替换 | 应用级对象池 |
| 分配粒度 | 通用内存块 | 固定大小对象 |
| 构造/析构 | 只分配内存 | 可以分离构造和分配 |
| 批量释放 | 不支持 | 支持 purge_memory() 一次性释放整个池 |
| 对象重用 | 无 | 释放的对象回到池中复用 |
Pool 相比 jemalloc 的优势场景:
- 链表/树节点管理:需要频繁 new/delete 节点,但生命周期跟随整个数据结构
- 游戏对象池:子弹、粒子等对象需要快速创建销毁,且经常批量清除
- 内存和构造分离:只想分配原始内存,稍后或选择性构造对象
- 避免频繁系统调用:即使 jemalloc 也有 overhead,Pool 完全在用户态
简单说:jemalloc 让 new/delete 更快,Pool 让你少用甚至不用 new/delete。
头文件: boost/pool/object_pool.hpp
#include <boost/pool/object_pool.hpp>
#include <iostream>
#include <vector>
class Node {
public:
int value;
Node* next;
Node(int v) : value(v), next(nullptr) {}
~Node() { std::cout << "Node " << value << " destroyed\n"; }
};
int main() {
// object_pool - 对象池
boost::object_pool<Node> nodePool;
std::cout << "Creating nodes from pool:\n";
Node* n1 = nodePool.construct(1);
Node* n2 = nodePool.construct(2);
Node* n3 = nodePool.construct(3);
n1->next = n2;
n2->next = n3;
std::cout << "Nodes linked: " << n1->value << " -> "
<< n1->next->value << " -> " << n2->next->value << "\n";
// 手动释放
nodePool.destroy(n1);
nodePool.destroy(n2);
nodePool.destroy(n3);
std::cout << "\nCreating more nodes:\n";
std::vector<Node*> nodes;
for (int i = 0; i < 1000; ++i) {
nodes.push_back(nodePool.construct(i));
}
std::cout << "Pool memory used: " << nodePool.get_memory_usage() << "\n";
std::cout << "Pool size: " << nodePool.get_free_count() << "\n";
// 清空池
nodes.clear();
nodePool.purge_memory();
std::cout << "After purge, free count: " << nodePool.get_free_count() << "\n";
return 0;
}需要链接的库: header-only
lexical_cast 类型转换
Boost.Lexical_cast 提供了类似 Python 的类型转换功能。
头文件: boost/lexical_cast.hpp
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <string>
#include <vector>
int main() {
// 字符串转数字
std::string strNum = "123";
int num = boost::lexical_cast<int>(strNum);
std::cout << "String to int: " << num << "\n";
double d = boost::lexical_cast<double>("3.14159");
std::cout << "String to double: " << d << "\n";
// 数字转字符串
int n = 456;
std::string str = boost::lexical_cast<std::string>(n);
std::cout << "Int to string: " << str << "\n";
// 其他类型转换
bool b = boost::lexical_cast<bool>("true");
std::cout << "String to bool: " << std::boolalpha << b << "\n";
// 容器转换
std::vector<int> vec = boost::lexical_cast<std::vector<int>>("[1,2,3,4,5]");
std::cout << "Vector from string: ";
for (int v : vec) {
std::cout << v << " ";
}
std::cout << "\n";
// 自定义类型的转换
struct Point {
int x, y;
};
try {
Point p = boost::lexical_cast<Point>("(10,20)");
std::cout << "Point: (" << p.x << ", " << p.y << ")\n";
} catch (const boost::bad_lexical_cast& e) {
std::cout << "Conversion failed: " << e.what() << "\n";
}
return 0;
}需要链接的库: header-only
总结
| 库 | 功能 | 需要链接的动态库 |
|---|---|---|
| timer | 计时器 | libboost_timer, libboost_chrono |
| algorithm/string | 字符串分割、处理 | header-only |
| circular_buffer | 环形缓冲区 | header-only |
| heap | 优先队列 | header-only |
| lockfree | 无锁数据结构 | header-only |
| string_algo | 字符串算法 | header-only |
| tokenizer | 字符串分词器 | header-only |
| pool | 内存池 | header-only |
| lexical_cast | 类型转换 | header-only |
注意: header-only 的库直接包含头文件即可使用。但某些情况下可能仍需要链接 libboost_system 等基础库。timer 需要链接 libboost_timer 和 libboost_chrono。





