Вот одна идея сэкономить место:
struct Outer {
int i;
struct Inner {
int j;
uint16_t where;
Outer& outer() {
Inner* first = this - where;
char* addr = reinterpret_cast<char*>(first) - offsetof(Outer, items);
return *reinterpret_cast<Outer*>(addr);
}
};
Inner items[1000];
Outer() {
for (uint16_t ii = 0; ii < 1000; ++ii)
items[ii].where = ii;
}
};
Если вы работаете на 64-битной машине с 32-битными целыми числами, это уменьшает sizeof(Inner)
с 16 до 8 байт без упаковки, илиУпаковка от 12 до 6 байт.
Если вы хотите сэкономить еще больше места, вы можете сделать это:
struct Outer {
int i;
struct Inner {
int j;
Outer& outer() {
Inner* sentinel = this;
while (sentinel.j != INT_MIN)
--sentinel;
char* addr = reinterpret_cast<char*>(sentinel) - offsetof(Outer, sentinel);
return *reinterpret_cast<Outer*>(addr);
}
};
Inner sentinel = {INT_MIN};
Inner items[1000];
};
Но тогда outer()
- это O (n) вместо O (1), и вы должны быть уверены, что INT_MIN
(или некоторое значение часового) никогда не используется в items
.