r/cpp 6d ago

C++26: std::inplace_vector

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

121 comments sorted by

View all comments

Show parent comments

1

u/Raknarg 18h ago

A more general solution to the problem would have been an inplace_allocator -- which requires a different API than allocator -- which could be applied to every container (standard or not).

This wouldn't fix anything. inplace_vector stores its data locally within the structure itself, while vector stores it through a pointer. You can't get around this, you need a different type who's designed to offer storage inside the vector. Allocator doesn't fix this, where is it gonna allocate to?

edit: I guess the allocator type itself has the storage? I didn't think about this but I guess this could actually work, but you still would need to fix all the requirements around resizing and whatnot

1

u/matthieum 15h ago

You're absolutely correct that std::allocator doesn't fit the bill...

... which is exactly why I advocate for a whole different API.

And yes, this would involve in-depth changes to anything taking this new API as they would no longer be able to take pointers, but would instead need to use "handles" of some sort, which would have some way to resolve into pointers when needed, and some rules about how long these pointers remain valid, etc...

I didn't say it was easy, I said it was generic :)

1

u/Raknarg 15h ago

And yes, this would involve in-depth changes to anything taking this new API as they would no longer be able to take pointers, but would instead need to use "handles" of some sort, which would have some way to resolve into pointers when needed, and some rules about how long these pointers remain valid, etc...

I don't think you'd need to change the allocator API, you'd just provide an allocator type that just has its storage internally as part of the allocator. You could do some shit like this

template<class T, std::size_t N>
struct inplace_allocator {
    alignas(T) std::byte buffer[sizeof(T) * N];

    T* allocate(std::size_t n) {
        if (n > N)
            throw std::bad_alloc{};

        return reinterpret_cast<T*>(buffer);
    }

    void deallocate(T*, std::size_t) noexcept {}
};

but I haven't thought about it enough to think of issues you'd run into by doing this.

1

u/matthieum 15h ago

Pointers are invalidated on move.

1

u/Raknarg 14h ago

good point