My container needs to store a little information about its elements. Normally, I store this separately from elements. However, I'd like to give users possibility to conserve memory by dedicating a field in element structure type for external use. E.g.:
struct MyStuff
{
int foo;
char bar;
mutable char dedicated_for_external_use; // Because of alignment, this field
// won't increase sizeof (MyStuff)
};
The idea here is that the field must not be accessed by anything but element's container. Since containers store a copy (much like std::vector
), it wouldn't be a problem if you added any given value x
to several containers.
How would you design an interface for this that, if possible, would meet the following requirements?
- Should be completely optional. I.e. it should be possible to automatically determine if given type provides such a field or not and then container would only use it if available.
- Ideally, wouldn't depend on type traits etc. as I need maximum compiler compatibility.
- Should be easy to use. I.e. if you can and want to enable this optimization for type
MyStuff
, you could do it with 3 lines of code, not 25. Internal complications, on the other hand, don't matter. - Should preferably exclude false positives completely. What I mean is: if you check for field
foo_bar
there is a small posibility that such field exists for a completely unrelated reason (and I think duck-typing is simply not for C++). A better way would be to check if type inherits marker classProvidesExternalUseField
from my library, as this can't be by accident.
EDIT
I know about Boost.Intrusive, but what I want is something different. If I go that way and create a hooks class with a single char
field, it cannot be used to conserve memory in many cases. If inherited type has an int
as first field, char
field will be padded to 4 bytes. I.e. you'd often need intricate knowledge of type internals to be able to "squeeze" such extern-use field in, but inheritance doesn't really provide it:
struct hooks { mutable char dedicated_for_external_use; };
struct MyStuff : hooks
{
int foo;
char bar;
};
Here, size of MyStuff
will be 12 bytes, not 8.