11

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

4

2 回答 2

4

似乎是不可能的。只operator new[]知道如何以T某种特定于实现的方式存储数组大小(如果有析构函数)(operator delete[]然后利用此信息)。因此,如果没有 new 表达式(并且没有调用元素构造函数),就没有可移植的方式来存储此信息。

于 2011-10-19T15:24:50.637 回答
1

然后尝试放置新的。

    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
    }
于 2011-11-25T09:08:02.060 回答