In some (lower-level) parts of my codebase I often have the need to allocate resizable array storage for certain objects, that usually are not default-constructible.
I created a simple class using std::aligned_storage
and I was wondering if it's safe and if it can be improved.
The user of the class has to keep track of the current capacity.
template<typename T> class ResizableArray
{
private:
using TStorage = std::aligned_storage_t<sizeof(T), alignof(T)>;
TStorage* data{nullptr};
public:
~ResizableArray() { delete[] data; }
void resize(std::size_t mSizeOld, std::size_t mSizeNew)
{
auto newData(new TStorage[mSizeNew]);
for(auto i(0u); i < mSizeOld; ++i) newData[i] = std::move(data[i]);
delete[] data;
data = newData;
}
auto& operator[](std::size_t mIdx) noexcept
{ return reinterpret_cast<T&>(data[mIdx]); }
const auto& operator[](std::size_t mIdx) const noexcept
{ return reinterpret_cast<const T&>(data[mIdx]); }
};
Example usage:
int main()
{
ResizableArray<Thing> a;
// Resize array capacity from 0 to 10
a.resize(0, 10);
for(auto i(0u); i < 10; ++i)
new (&a[i]) Thing{/* something */};
return 0;
}
reserve()
and std::vector::emplace_back()
?vector<T>
does requireT
to be default-constructible. – firda yesterdaystd::vector<T>
only requires T to be default constructable if you features of vector that use the default constructor. If you don't use those features then this requirement is not required because of SFINAE. So the only thing stopping you using a vector is re-size. Rather than use re-size just reserve and emplace back your elements that you want. – Loki Astari 3 hours ago