c++macrosmetaprogramming

Using C++ macros to construct a method name to call


I have a class Foo from a third party library that has a lots of setters with a string argument named as set_parameter_name(std::string value). And I need to configure an instance of the class using a simple parser that returns a needed value of the required parameter like this:

std::string value = parser.parse("parameter_name");

So the code looks like:

Foo foo = Foo();
Parser parser = Parser();
foo.set_a(parser.parse("a"));
foo.set_b(parser.parse("b"));
// lots of strings
foo.set_z(parser.parse("z");

This code is pretty ugly so I'm trying to replace it with a C++ macro. The idea is using a list of names to generate code automatically by preprocessor but I cannot imagine how to do that.

If I deal with the parameters as strings, I cannot convert it to set_param_name in macro:

#define PARAM_LIST "a", "b", "c", "d" // lots of elements

#define PARAM_SETTER(foo, param, parser) ({ \
foo.set_#param(parser.parse(param)); \ // <- as I understand, it's impossible to create a method name from a string value.
})

Foo foo = Foo();
Parser parser = Parser();
for (auto param : std::string[]{PARAM_LIST}) PARAM_SETTER(foo, param, parser);

Alternatively, I can define the list as variables, but in this case I don't know how to save a variable name when it passed to macro:

#define PARAM_LIST a, b, c, d

#define PARAM_SETTER(foo, param, parser) ({ \
foo.set_#param(parser.parse("#param"); \
})

Foo foo = Foo();
Parser parser = Parser();
std::string PARAM_LIST;
for (auto param : std::string[]{PARAM_LIST}) PARAM_SETTER(foo, param, parser); // the problem is variable name to stringify is just 'param'

The 3rd method is possibly using VA_ARGS in macro but I don't know how.


Solution

  • With X MACRO,

    #define LIST_OF_VARIABLES \
        X(a) \
        X(b) \
        X(c) \
        X(z) \
    

    you might do:

    #define X(var) foo.set_##var(parser.parse(#var));
    LIST_OF_VARIABLES
    #undef X
    

    Demo