Размещение нового с перегруженным обычным новым оператором

У меня есть объект типа MyType, который по причинам SSE должен быть выровнен по 16 байт. Итак, я написал распределитель и перегрузил операторы new. Методы в MyType:

inline static void* operator new(size_t size) {
    awesome::my_allocator<MyType,16> alloc;
    return alloc.allocate(size);
}
inline static void* operator new[](size_t size) { return operator new(size); }
inline static void operator delete(void* ptr) {
    awesome::my_allocator<MyType,16> alloc;
    alloc.deallocate(reinterpret_cast<MyType*>(ptr),0); //last arg ignored in my impl
}
inline static void operator delete[](void* ptr) { operator delete(ptr); }

Теперь, по причинам локальности кэша, мне нужно скопировать-построить экземпляр в определенную часть 64-байт-выровненной памяти:

void MyType::copy_into(uint8_t* ptr) const {
    new (reinterpret_cast<MyType*>(ptr)) MyType(*this);
}

GCC говорит мне:

error: no matching function for call to ‘MyType::operator new(sizetype, MyType*)’

ICC сообщает мне:

error : function "MyType::operator new" cannot be called with the given argument list
1>              argument types are: (unsigned __int64, MyType *)

Как я понимаю, новый оператор размещения обеспечивается реализацией С++ (или, возможно, с помощью <new>, который я также пробовал #include ing?) и просто возвращает свой аргумент (new делает доступной память и размещение нового - это программатор, говорящий, что данная память доступна).

Любопытно, что ошибка не возникает, когда новые (обычные!) новые операторы, определенные выше, не входят в класс. В самом деле, MyOtherType, который не определяет их, отлично работает.

Вопрос: что происходит? Как его исправить?

Ответ 1

Поскольку вы определили operator new в своем классе, вам нужно использовать глобальный new, чтобы использовать его версию размещения.

#include <new>

...

::new (reinterpret_cast<MyType*>(ptr)) MyType(*this);