Automatic collection of std :: map with function pointers
I am developing a script language in C ++ that uses functions that are "built" into the interpreter. I use the following construct to map function names to their corresponding pointers:
typedef void(*BuiltInFunction)(Context*);
typedef std::unordered_map<std::string, BuiltInFunction> BuiltinFunctionsMap;
where Context
is the custom class.
Then I have function declarations:
namespace BuiltIns {
void _f_print(Context* context);
void _f_error(Context* context);
void _f_readline(Context* context);
void _f_read(Context* context);
void _f_readchar(Context* context);
void _f_eof(Context* context);
...
}
And finally, a procedure that populates the map with actual pointers:
BuiltinFunctionsMap BuiltIns::populateFunctions() {
BuiltinFunctionsMap funcMap;
// Standard I/0
funcMap["print"] = &BuiltIns::_f_print;
funcMap["error"] = &BuiltIns::_f_error;
funcMap["readline"] = &BuiltIns::_f_readline;
funcMap["read"] = &BuiltIns::_f_read;
funcMap["readchar"] = &BuiltIns::_f_readchar;
funcMap["eof"] = &BuiltIns::_f_eof;
...
return funcMap;
}
I am asking if there is a way to automatically generate a population function from a function declaration using templates or something similar. I currently use regex, which is simple enough, but I have to do it every time I add new features, and it's cumbersome.
source to share
I don't know if this is really a useful answer, but you can use a preprocessor to do some pretty protein stuff :
#include <iostream>
#include <map>
#include <string>
class Context {};
typedef void (*BuiltInFunction)(Context*);
// a list of your function names
#define FN_NAMES \
X(foo) \
X(bar) \
X(baz)
// this declares your functions (you also have to define them
// somewhere else, e.g. below or in another file)
#define X(a) void _f_ ## a ## _print(Context *context);
namespace BuiltIns {
FN_NAMES
}
#undef X
// a global map initialized (using C++11 initializer syntax)
// to strings mapped to functions
#define X(a) {#a, &BuiltIns::_f_ ## a ## _print},
std::map<std::string, BuiltInFunction> g_fns = {
FN_NAMES
};
#undef X
int main() {
g_fns["foo"](NULL); // calls BuiltIns::_f_foo_print(NULL)
}
// (these have to be defined somewhere)
namespace BuiltIns {
void _f_foo_print(Context *context) {
std::cout << "foo\n";
}
void _f_bar_print(Context *context) {
std::cout << "bar\n";
}
void _f_baz_print(Context *context) {
std::cout << "baz\n";
}
}
This approach has the advantage of automatically generating, for example, a string "foo"
and binding it to a function _f_foo_print
. The downsides are horrible preprocessing trickery and the fact that you still have to deal with foo
in two places.
source to share