Since C++11 the only general requirement on the element of a vector is that it satisfies the Erasable requirement with the used allocator. It basically requires that the object type can be destroyed through a properly rebound std::allocator_traits::destroy
.
With the standard allocator std::allocator
, this requirement was not satisfied before C++20, because std::allocator::destroy
would try to use a simple (pseudo-)destructor call which is well-formed only for class and scalar types, not for array types.
Since C++20 std::allocator
's destroy
is defaulted through std::allocator_traits
to use std::destroy_at
and std::destroy_at
is extended to support array types by calling itself recursively on the array elements. So the Erasable requirement is now fulfilled with array types and it is not generally forbidden to use array types in std::vector
with the default allocator anymore.
However, when actually constructing elements in the vector, the vector must use the allocator's construct
, which was also defaulted with C++20 to use std::construct_at
. Unfortunately std::construct_at
doesn't work with arrays, which is probably unintentional (see open LWG issue 3436). So currently it is not possible to construct any elements in such a vector with the default allocator and the only way to use std::vector<float[4]>
is to construct an empty instance.
Even when this issue is resolved, there is however almost no use for such a vector. The only thing one can do with it is constructing an instance with a given number of value-initialized elements and then operate on this fixed-size vector's elements. None of the modifiers can be used because they require some form of copying or moving of the element type, which isn't possible for array types. Such a vector can be moved and swapped, but not copied.