I'm implementing a resource-allocating cloning operation for an array of type T. The straightforward implementation uses new T[sz] followed by a std::copy call from the source into the new array. It walks memory twice.
I'd like to allocate raw memory and then use std::uninitialized_copy so I only walk memory once for performance reasons. I know how to accomplish this when a custom allocator is used (Allocator.allocate followed by std::uninitialized_copy), and I know how to accomplish this using std::allocator (which employs ::operator new following lib.allocator.members in section 20.4.1.1 of the specification). My concern is that a std::allocator-based approach seems wrong for types T where T::operator new has been defined. I know I can detect such a situation using Boost.TypeTraits' has_new_operator.
Is there a simple, standards-compliant way to allocate-and-then-initialize raw memory in a fashion that will respect an overridden new (and does so passing over memory only once)? If not, does using SFINAE to dispatch between an implementation employing std::allocator and one using the overridden operator new seem reasonable? FWIW, grepping through Boost does not show such a use of the has_new_operator trait.
Thanks, Rhys
Seems it isn't possible. Only operator new[] knows how to store array size (if T has a destructor) in some implementation-specific way (operator delete[] then utilizes this info). Therefore, there is no portable way to store this information without new expression (and without calling elements constructors).
try placement new then.
typedef std::string T;
T src[5];
char* p = new char[sizeof(T)* 5];
T* dest = (T*)p;
for(int i = 0;i < 5; ++i)
{
new(dest + i) T(src[i]); //placement new
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With