std::inplace_vector is a vector that never touches the heap
There has always been a gap between std::array and std::vector. std::array<T, N> is fixed-size: N elements, always, no push_back. std::vector<T> is dynamic but pays for it with a heap allocation you cannot always afford, in an interrupt handler, a real-time audio callback, or a kernel of a hot loop. For decades the answer was a hand-rolled “static vector”: a raw buffer plus a count. Every serious codebase has one. Boost has one. The EASTL has one.
C++26 puts it in the standard library as std::inplace_vector<T, N> (P0843). It is a contiguous sequence container with a dynamic size up to a compile-time capacity N, and its storage lives inline, inside the object itself. No allocator, no heap, ever.
The demo fills an inplace_vector<int, 4> to capacity and prints it:
size=4 capacity=4 elements=[10, 20, 30, 40]
try_push_back(50) -> rejected (at capacity)
capacity() is fixed at 4 by the type. size() grows as you push_back, just like a vector. And the whole thing sits wherever you put it: on the stack here, but equally as a class member or a static, with no allocation at any point.
The full case is a choice, not a crash
Because capacity is bounded, inplace_vector has to answer a question vector never faces: what happens when you push past N? It gives you both answers.
push_backpast capacity throwsstd::bad_alloc. It keeps the familiar interface, so generic code that expects vector-like semantics still works.try_push_backpast capacity does not throw. It reports the failure instead, so the full case is an ordinary branch. That is what the demo uses, and it is the version you want on a path where exceptions are banned or too expensive.
There is also unchecked_push_back for when you have already proven there is room and want no check at all.
Why it matters beyond embedded
The obvious audience is embedded and real-time, where heap allocation is often simply forbidden. But the type earns its place in ordinary code too. A small, known-bounded collection, the parsed fields of a record, the corners of a bounding box, a fixed roster of worker handles, is both faster and clearer as an inplace_vector<T, N> than as a vector<T> you immediately reserve. You state the bound in the type, and the compiler holds you to it, with no allocation to pay for or fail.
It sits naturally alongside the other allocation-avoidance tools: where pmr lets a vector draw from a stack buffer, inplace_vector removes the allocator from the picture entirely. GCC 16.1’s libstdc++ ships it today.
Sources: P0843R14 “inplace_vector” · cppreference: std::inplace_vector.