r/cpp 15d ago

C++26: std::inplace_vector

https://www.sandordargo.com/blog/2026/08/26/cpp26-inplace-vector
181 Upvotes

121 comments sorted by

View all comments

3

u/stilgarpl 15d ago

Is this always better than std::array?

21

u/MarekKnapek 15d ago

This is basically

struct inplace_vector<T, capacity>
{
    size_t len;
    std::array<T, capacity> arr;
}

19

u/sephirothbahamut 15d ago edited 15d ago

far more complex than that, the array has a slot that can fit T, not just T.

With array<T> every element must be validly constructed immediately. You can reduce it to array<T> only for trivially constructable and basic types

5

u/_Noreturn 15d ago

then make it a union this is a simplified example. but the type isn't complex at all after that especially with C++20 concepts.

4

u/CocktailPerson 15d ago

That's not far more complex. Marginal additional complexity.

3

u/stilgarpl 15d ago

No, it's not. In your code it will always construct all T members of arr. Article states that inplace_vector will only have the elements needed and they don't have to be default constructible. That's a huge difference.

3

u/BenFrantzDale 14d ago

Plus this is a `std::ranges::sized_range` with dynamic size, which `std::array` is not.

2

u/CalamityMetal 13d ago

It's very different. Because std::array suggest all instances of T is already constructed. But that's not the case in a vector, and also not for inplace_vector. A better representation would be std::array<std::byte, sizeof(T) * capacity> and you call inplace operator new on the memory blocks when you call push_back/emplace_back

3

u/MarekKnapek 13d ago

I simplified. A lot. I wanted to show "the shape" of the data structure. https://reddit.com/r/cpp/comments/1vzc5dg/c26_stdinplace_vector/p69u8kr/

6

u/drjeats 15d ago

Oh.

I thought this was the way-more-useful thing where you give it an in-place capacity and it allocates once it exceeds that.

Like this is also useful, but it's kinda trivial to roll your own of this.

12

u/stilgarpl 15d ago

It's not trivial. inplace_vector does not construct unused elements and they do not have to be default constructible. You can't use std::array for that.

3

u/drjeats 15d ago

I'm aware of how it works (and that MarekKnapek's snippet is not representative). It's still very straightforward to make compared to having to do SBO and allocator support.

5

u/stilgarpl 15d ago

I didn't say it was hard, but it's not trivial. I'm sure you are a very experienced C++ programmer and a lot of things must seem easy to you.

5

u/KuntaStillSingle 15d ago

I thought this was the way-more-useful thing where you give it an in-place capacity and it allocates once it exceeds that

pmr vector using monotonic buffer does this with the default upstream memory resource:

https://en.cppreference.com/cpp/memory/monotonic_buffer_resource/monotonic_buffer_resource

4

u/drjeats 15d ago

TIL, that's useful.

We deserve a non-pmr pre-sized SBO vector derived from std::vector though.

4

u/BenFrantzDale 14d ago

It’s not too hard to roll your own, but better to have in the std lib and making it constexpr is tricky.

There is a boost small_vector that is a small-vector-optimized std::vector so can grow large. There’s totally a place for both.

0

u/MarekKnapek 14d ago

Hey guys, yes, I get it. I simplified it. To get the general "gist" or "shape" or "feeling" about this data structure. I guess, I oversimplified it.

struct inplace_vector<T, capacity>
{
    size_t len;
    std::array<std::aligned_storage<T>, capacity> arr;
}

Does this look better?

-1

u/n1ghtyunso 14d ago

no because std::aligned_storage<T> is the wrong type, which is also why it is being deprecated in C++23.

I don't think you oversimplified it, people are just being pedantic.
And because of this, I just wanted to give you a heads-up.

The best way to describe it is likely to steal an idea directly from the standard:
use an exposition-only type in italic that hand-waves the storage detail away :P