Created
June 21, 2012 00:16
-
-
Save quietfanatic/2963094 to your computer and use it in GitHub Desktop.
C++11 struct-array hybrid
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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