2015-10-07 10 views
12

Mam obiekt typu MyType, który z powodów SSE musi być wyrównany do 16 bajtów. Napisałem więc alokator i przeciąłem operatorów new. Metody MyType:Nowe miejsce docelowe z przeciążonym zwykłym nowym operatorem

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); } 

Teraz ze względów cache-lokalności, muszę skopiować-konstruować wystąpienie do konkretnego kawałka 64-bajtowy wyrównany pamięci:

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

GCC mówi mi:

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

ICC mi mówi:

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

Jak rozumiem, nowy operator placement jest przez C++ realizacji (lub ewentualnie przez <new>, który Próbowałem też #include ing?) I po prostu zwraca jej argument (new sprawia pamięć dostępny i rozmieszczenie new jest programistą informującym, że dana pamięć jest dostępna).

Co ciekawe, błąd robi nie wystąpić, gdy zwykły (!) Nowych operatorów określone powyżej są nie w klasie. Rzeczywiście, MyOtherType, który ich nie definiuje, działa dobrze.

Pytanie: co się dzieje? Jak mam to naprawić?

+0

Prawdopodobnie przeładuj nowe, aby pobrać 2 parametry - operator new (rozmiar, wyrównanie) - aby normalne wiadomości o 1 paramie nie uległy zmianie. Może to obejść kompilator narzekając, pozwalając mu użyć wbudowanego typu. Przeciążenie rzutem kontra nieładowaniem może również powodować pewne problemy. –

+0

Czy wszystko dzieje się w jednej jednostce tłumaczeniowej? –

+0

Nowe miejsce jest zwykle używane do "umieszczenia obiektu w już przydzielonej pamięci", może trzeba przeciążyć nowy operator rozmieszczenia, aby zbiegło się z twoją implementacją? – AJG85

Odpowiedz

8

Po zdefiniowaniu operator new w swojej klasie, musisz użyć globalnej wersji new, aby użyć wersji miejsca docelowego.

#include <new> 

... 

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

Potwierdzono, że to rozwiązuje problem. Jak rozumiem, w bieżącym obszarze nazw wystąpiło przeciążenie 'new', więc nie sprawdzono globalnej przestrzeni nazw, aby znaleźć przeciążenie (miejsce "nowe"), które by zadziałało? – imallett

+0

Nie powiedziałbym "w aktualnym obszarze nazw", powiedziałbym "w samej" klasie ". Są dwa etapy związane z dopasowaniem wywołania funkcji - wyszukiwanie nazwy i przeciążenie rozkład. Jeśli nazwa znajduje się w klasie lub otaczającej przestrzeni nazw, to wyszukiwanie kończy się. Jeśli wyszukiwanie prowadzi do wielu funkcji, wówczas zaczyna działać tylko rozdzielczość przeciążania. –

Powiązane problemy