Reputation: 3598
How do I create an array on the heap and initialize it at construction time from another array?
template <typename T>
T* Copy(T* myOriginalArray, size_t myOriginalArraySize)
{
T* copy = new T[myOriginalArraySize]; // copy data from myOriginalArray here too
return copy;
}
I could create the array and then use std::copy, but this would require the array contents to have an empty constructor. You can assume the object has a copy and move constructor. I have access to C++17.
Upvotes: 0
Views: 108
Reputation: 21150
You use ::operator new
and std::uninitialized_copy
#include<memory>
#include<new>
template<typename T>
T* Copy(T* src, size_t sz)
{
auto buf = static_cast<T*>(::operator new(sizeof(T) * sz));
std::uninitialized_copy(src, src + sz, buf);
return buf;
}
And possibly move, with a bit more hassle.
#include<utility>
template<typename T>
T* Move(T* src, size_t sz)
{
auto buf = static_cast<T*>(::operator new(sizeof(T) * sz));
for(size_t i = 0; i < sz; i++)
new (buf + i) T(std::move(src[i]));
return buf;
}
This is not really a great idea, considering then you have to deallocate with some crazy code
template<typename T>
void Delete(T* src, size_t sz)
{
for(size_t i = 0; i < sz; i++)
src[i].~T();
::operator delete(src);
}
Do consider using std::vector
instead.
Q: Why index with size_t
instead of using T*
?
A: As it turns out, it is currently slightly faster with indexing.
Upvotes: 2
Reputation: 59711
Not sure if this is what you are asking, but you can just allocate the memory first and then use placement new
(which is basically what preallocating STL containers do anyway).
template <typename T>
T* Copy(T* myOriginalArray, size_t myOriginalArraySize)
{
auto t_size = sizeof(T);
T* copy = (T *) new char[myOriginalArraySize * t_size];
for (size_t i = 0; i < myOriginalArraySize; i++)
{
new (copy + i) T(*(myOriginalArray + i));
}
return copy;
}
Upvotes: 0