@@ -66,21 +66,32 @@ int main()
6666
6767第二个是 ` std::inplace_vector<T, N> ` ,C++26 进的标准(提案 P0843)。它填的是 ` array ` 和 ` vector ` 中间的缝:` array<T, N> ` 大小编译期定死、不能变;` vector<T> ` 能变长但要堆分配(扩容时 new 新块、拷贝、释放旧块)。很多时候你要的是「容量上限编译期知道、运行期 size 可变、但绝不碰堆」——` inplace_vector ` 就是干这个的。它的元素** 直接存在对象内部** (对象本身占 ` sizeof(T) * N ` 那块空间,放栈上或静态区),运行期可以在 0 到 N 之间增删,不 new、不扩容、不拷贝搬移。
6868
69- 最讨喜的一个性质是:** 当 ` T ` 是 trivially copyable 时,` inplace_vector<T, N> ` 本身也是 trivially copyable** 。这意味着它可以整体 ` memcpy ` 、可以放进寄存器、可以安全交给 DMA——这些对嵌入式和系统编程极重要,[ array 深入] ( 02-array.md ) 讲过的「连续内存 + trivially copyable」红利,inplace_vector 同样吃到,而 ` std::vector ` 因为持有一个堆指针、不是 trivially copyable,是吃不到的。容量超限时的行为也设计得克制:` push_back ` 超过 N 会抛 ` std::bad_alloc ` (异常关闭时退化为 terminate),而想避免异常可以用 C++26 的 ` try_push_back ` /` try_emplace_back ` ,它们超限时不抛、返回一个错误指示 ,适合 ` -fno-exceptions ` 环境。
69+ 最讨喜的一个性质是:** 当 ` T ` 是 trivially copyable 时,` inplace_vector<T, N> ` 本身也是 trivially copyable** 。这意味着它可以整体 ` memcpy ` 、可以放进寄存器、可以安全交给 DMA——这些对嵌入式和系统编程极重要,[ array 深入] ( 02-array.md ) 讲过的「连续内存 + trivially copyable」红利,inplace_vector 同样吃到,而 ` std::vector ` 因为持有一个堆指针、不是 trivially copyable,是吃不到的。容量超限时的行为也设计得克制:` push_back ` 超过 N 会抛 ` std::bad_alloc ` (异常关闭时退化为 terminate),而想避免异常可以用 C++26 的 ` try_push_back ` /` try_emplace_back ` ,它们超限时不抛、返回类型是std::optional<T&>, 空值来代表失败 ,适合 ` -fno-exceptions ` 环境。
7070
7171``` cpp
7272#include < cstdio>
7373#include < inplace_vector>
74+ #include < type_traits>
7475
7576int main ()
7677{
7778 std::inplace_vector<int, 4> v; // 容量上限 4,绝不堆分配
79+ static_assert (std::is_trivially_copyable_v<decltype(v)::value_type>); // 由于存储类型int是trivially copyable
80+ static_assert(std::is_trivially_copyable_v<decltype(v)>); // 整个inplace_vector都会是trivially copyable
81+
7882 v.push_back(1);
7983 v.push_back(2);
80- v.push_back(3); // size 现在 3,还能再塞一个
81- std::printf ("size = %zu, capacity = %zu\n", v.size(), v.capacity());
82- // 再 push 到满:v.push_back(4) 成功;v.push_back(5) 超容量,抛 bad_alloc
83- // 想避免异常用 try_push_back / try_emplace_back——超限不抛,返回失败指示
84+ v.push_back(3);
85+ v.push_back(4); // size 现在 4,无法再塞了
86+ std::printf ("size = %zu, max_size = %zu, capacity = %zu\n", v.size(), v.max_size(), v.capacity());
87+ // 此时如果 v.push_back(5) 超容量,抛 bad_alloc
88+ // 想避免异常用 try_push_back / try_emplace_back——超限不抛,返回std::optional<T&>, 空值来代表失败
89+ std::optional<int&> res = v.try_push_back(5);
90+ if (res.has_value()) {
91+ std::printf("successfully pushed the fifth element %d", res.value());
92+ } else {
93+ std::printf("failed to push the fifth element due to out of fixed capacity");
94+ }
8495 return 0;
8596}
8697```
@@ -90,7 +101,8 @@ g++ -std=c++26 -O2 -o /tmp/ipv_demo /tmp/ipv_demo.cpp && /tmp/ipv_demo
90101```
91102
92103``` text
93- size = 3, capacity = 4
104+ size = 4, max_size = 4, capacity = 4
105+ failed to push the fifth element due to out of fixed capacity
94106```
95107
96108` inplace_vector ` 和 ` array ` 的边界要拎清:` array<T, N> ` 的 size 恒等于 N,是定长;` inplace_vector<T, N> ` 的容量上限是 N,但 size 在 0 到 N 之间运行期可变。要定长用 array,要「上限已知 + 运行期可变 + 不堆分配」用 inplace_vector。
0 commit comments