Is it possible to implement a constexpr static_vector?
By static_vector, I mean a vector which has its storage space inside the vector (not heap allocated) and it cannot grow beyond the compile-time CAPACITY. Something like this:
template <typename T, int CAPACITY>
struct static_vector {
unsigned char data[sizeof(T)*CAPACITY];
int size = 0;
template <typename ...PARAMETERS>
constexpr void emplace_back(PARAMETERS &&...parameters) {
new(data + size * sizeof(T)) T(std::forward<PARAMETERS>(parameters)...);
size++;
}
constexpr const T &operator[](int idx) const {
return std::launder(reinterpret_cast<const T *>(data))[idx];
}
};
(hopefully this implementation is UB-free).
If I try to use this implementation, I get various constexpr-related errors. Here is a little test program (godbolt):
struct Foo {
int x;
constexpr Foo(int x) : x(x) { }
};
constexpr int fn() {
static_vector<Foo, 3> a;
a.emplace_back(1);
a.emplace_back(2);
return a[0].x + a[1].x;
}
int main() {
constexpr int v = fn();
printf("%d\n", v);
}
As far as I know, it is possible to do this if heap allocated storage is used. The question is, is it possible to do this using an "embedded" space, like static_vector does? I know that this is not possible with older standards, but are we going to have something in the next standard which makes this possible?
(I also tried to implement this using a union, but it fails in a different way)
std::inplace_vectoris that it is proposed for C++26. So, most current implementations do not support it, and there is still potential that it will not make it into the standard.boost::container::static_vector,boost::container::small_vector,llvm::SmallVector,folly::small_vector,eastl::fixed_vectoralthough I haven't check if any of them can be constexpr