Is it possible to redefine a global new operator based on the selected properties of an object type?

I am experimenting with updating our combined fixed-block memory allocation block to take advantage of features like C ++ 11.

Currently, it is possible to force distribution of any object anywhere that should be sent to the correct pool by overriding the global new operator in the traditional way, for example

void* operator new (std::size_t size) { // if-cascade just for simplest possible example if ( size <= 64 ) { return g_BlockPool64.Allocate(); } else if ( size <= 256 ) { return g_BlockPool256.Allocate(); } // etc .. else assume arguendo that we know the following will work properly else return malloc(size); } 

In many cases, we could improve performance if objects could be sent to different pools depending on type types such as is_trivially_destructible . Is it possible to create a template global new operator that knows about the distributed type, and not just the requested size? Something equivalent

 template<class T> void *operator new( size_t size) { if ( size < 64 ) { return std::is_trivially_destructible<T>::value ? g_BlockPool64_A.Allocate() : g_BlockPool64_B.Allocate(); } // etc } 

Overriding the new element operator in each class will not work here; we really need this to automatically work for any placement anywhere. Posting a new one won't work: requiring each address to look like

 Foo *p = new (mempool<Foo>) Foo(); 

too bulky and people will forget to use it.

+8
c ++ c ++ 11 typetraits
source share
1 answer

The short answer is no. The distribution / release functions have the following signatures:

 void* operator new(std::size_t); void* operator new[](std::size_t); void operator delete(void*); void operator delete[](void*); 

Most deviations from these signatures will result in your function not being used at all. In a typical implementation, you basically replace the default implementations at the linker level - i.e. An existing function has some specific malformed name. If you provide a function with a name that distorts an identical result, it will be bound instead. If your function does not work with the same name, it will not be bound.

In some cases, you can use the template as you suggested, but if so, it will lead to undefined behavior. Depending on how you organized the headers (for example), you could finish the code by mixing the use of your template with the default functions, and at that moment what you could best hope for would be that it is fast and pure red.

+3
source share

All Articles