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