Skip to content

Instantly share code, notes, and snippets.

@quietfanatic
Created June 21, 2012 00:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save quietfanatic/2963094 to your computer and use it in GitHub Desktop.
Save quietfanatic/2963094 to your computer and use it in GitHub Desktop.
C++11 struct-array hybrid
// Struct-Array Hybrids
// In many situations it is useful to have a static collection of objects
// that can be accessed either by name or by number.
// Previously, you would have to declare an array of unnamed items, followed
// by either an enum or a series of const references. This made it difficult
// to modify by hand and to ensure that the right names were matched to the
// right objects. It also took twice as many code lines.
// However, C++11's non-static data member initializers allow you to define
// the items symbolically in a struct, and rely on the way the struct is
// stored to get numeric access.
// Note: Since it will be accessed like a raw C array, every item in the
// struct must have the same type (or binary-compatible types). A silent bug
// will occur if you declare members of binary-incompatible types in the
// struct. This should be easy to prevent, though, and in the usual case of
// a completely homogenously-typed collection, almost impossible to do by
// accident.
// Despite the seeming dirtiness of the use of a typecast, I believe that
// this construct will be far less error-prone than the traditional
// approaches.
// A potential disadvantage of this approach is that it is not clear how to
// separate interface (header) from implementation (code). If you need to do
// that, probably using an array+enum is your best bet.
#include "stdio.h"
#define CE constexpr
typedef unsigned int uint;
struct Things {
uint a = 1;
uint b = 2;
uint c = 3;
uint d = 4;
CE uint& operator [] (int i) const {
return ((uint*)this)[i];
}
} things;
const uint n_things = sizeof(things) / sizeof(uint);
int main () {
// Access like an array
// (looping over all items saves typing and code size)
for (uint i = 0; i < n_things; i++) {
printf("things[%u] = %u\n", i, things[i]);
}
// Access like a struct
// (names are more convenient for individual access than numbers)
printf("things.c = %u\n", things.c);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment