Вы слышали о boost::optional
?
Должен признать, что у меня нет ясности относительно реальной проблемы здесь ... но boost :: option позволяет хранить по значению и все же знать, была ли инициализирована фактическая память. Я также допускаю строительство и разрушение на месте, так что я думаю, что это может подойти.
EDIT
Мне кажется, я наконец-то понял проблему: вы хотите иметь возможность размещать много объектов в разных точках памяти, и вы хотите знать, действительно ли память в этой точке содержит объект или нет .
К сожалению, у вашего решения есть огромная проблема: оно неверно. Если когда-либо T
может быть каким-либо образом представлен в виде null
битовой комбинации, тогда вы будете думать, что это унифицированная память.
Вам придется прибегнуть к помощи, чтобы добавить хотя бы один бит информации. На самом деле это немного, ведь это всего лишь 3% прироста (33 бита на 4 байта).
Вы можете, например, использовать какой-нибудь mimick boost::optional
, но в виде массива (чтобы избежать потери заполнения).
template <class T, size_t N>
class OptionalArray
{
public:
private:
typedef unsigned char byte;
byte mIndex[N/8+1];
byte mData[sizeof(T)*N]; // note: alignment not considered
};
Тогда это так просто:
template <class T, size_t N>
bool OptionalArray<T,N>::null(size_t const i) const
{
return mIndex[i/8] & (1 << (i%8));
}
template <class T, size_t N>
T& OptionalArray<T,N>::operator[](size_t const i)
{
assert(!this->null(i));
return *reinterpret_cast<T*>(mData[sizeof(T)*i]);
}
note : Для простоты я не рассматривал вопрос выравнивания. Если вы не знаете о предмете, прочитайте об этом, прежде чем возиться с памятью:)