Обновление
Проверьте ответ Роберта Найта!Использует C ++ 11, но гораздо чище, чем этот ...
Оригинальный ответ
Как насчет этого мерзкого хака:
namespace priv {
#define PRIVATE_STATICMEM(_A_) \
template <size_t size> \
struct StaticMem<size,_A_> { \
__declspec(align(_A_)) char data[size]; \
void *operator new(size_t parSize) { \
return _aligned_malloc(parSize,_A_); \
} \
void operator delete(void *ptr) { \
return _aligned_free(ptr); \
} \
};
template <size_t size, size_t align> struct StaticMem {};
template <size_t size> struct StaticMem<size,1> {char data[size];};
PRIVATE_STATICMEM(2)
PRIVATE_STATICMEM(4)
PRIVATE_STATICMEM(8)
PRIVATE_STATICMEM(16)
PRIVATE_STATICMEM(32)
PRIVATE_STATICMEM(64)
PRIVATE_STATICMEM(128)
PRIVATE_STATICMEM(256)
PRIVATE_STATICMEM(512)
PRIVATE_STATICMEM(1024)
PRIVATE_STATICMEM(2048)
PRIVATE_STATICMEM(4096)
PRIVATE_STATICMEM(8192)
}
template <typename T, size_t size> struct StaticMem : public priv::StaticMem<sizeof(T)*size,__alignof(T)> {
T *unhack() {return (T*)this;}
T &unhack(size_t idx) {return *(T*)(data+idx*sizeof(T));}
const T &unhack() const {return *(const T*)this;}
const T &unhack(size_t idx) const {return *(const T*)(data+idx*sizeof(T));}
StaticMem() {}
StaticMem(const T &init) {unhack()=init;}
};
Выглядит страшно, но вам нужно все это только один раз (желательно в каком-то хорошо скрытом заголовочном файле :)).Тогда вы можете использовать его следующим образом:
StaticMem<T,N> array; //allocate an uninitialized array of size N for type T
array.data //this is a raw char array
array.unhack() //this is a reference to first T object in the array
array.unhack(5) //reference to 5th T object in the array
StaticMem<T,N> array;
может появиться в коде, но также и как член более крупного класса (именно так я использую этот хак) и должен также вести себя правильнопри выделении в куче.
Исправление ошибки:
Строка 6 примера: char data[_A_]
исправлено в char data[size]