4 ms·
I don’t think I follow, do you mind giving a concrete example?
by skribanto 2y ago
I don’t think I follow, do you mind giving a concrete example?
- rcxdude 2y agoBasically, instead of faffing around with undefing values and including different files, you define your list like this: #define AN_X_LIST(X) \ X(foo, bar) \ X(bar, baz) And then you use it like so: #define AN_ASSIGNMENT_STATEMENT(a,b) a = STRINGIFY(b); And so AN_X_LIST(AN_ASSIGNMENT_STATEMENT) Will expand to foo = "bar"; bar = "baz"; The nice thing about this approach is you can define multiple lists and macros, and make higher order macros which use them. I have a system like this which allows me to define reflective structs in C++ easily, i.e. I define a struct like: #define STRUCT_FOO_LIST(X) \ X(int, bar, 0), \ X(float, baz, 4.0), DECLARE_REFLECTIVE_STRUCT(Foo, STRUCT_FOO_LIST); (where DECLARE_REFLECTIVE_STRUCT basically just does the same dance as above with passing different per-element structs into the list that it is passed for the struct definition, and other utility functions associated with it) which then makes a struct Foo with members bar and baz with the right types and default values, but also I can do 'foo_instance.fetch_variant("baz")' and other such operations. The biggest pain with this approach is it's basically dealing with a bunch of multi-line macros, so it can get messy if there's a typo somewhere (and I strongly recommend an auto-formatter if you don't like having a ragged line of backslashes to the right of all the code that uses it).
- deleted 2y ago[deleted]
- elteto 2y ago_This_ is the best pattern for X macros, without any of that noise of undef'ing anything. My approach is to wrap the list elements with two macros: an inner transformation one and an outer delimiter, like so: #define AN_X_LIST(X, DELIM) \ DELIM(X(int, foo)) \ DELIM(X(int, bar)) \ X(std::string, baz) Then you can compose different pieces of code for different contexts by just swapping out the delimiter. A very contrived example: #define SEMICOLON(x) x; #define COMMA(x) x, #define DECLARE(type, var) type var #define INIT(type, var) var{} struct s { AN_X_LIST(DECLARE, SEMICOLON); s() AN_X_LIST(INIT, COMMA) {} };