假设我有一些反射元数据,其中包含以下信息:
enum class type { t_int, t_double, t_str /* etc... */ };
struct meta_data
{
void* function;
void* instance;
std::vector<type> param_types;
};
std::map<std::string, meta_data> ftable;
我想调用这张地图中的函数,给定函数名和参数都是字符串。我的问题不是转换参数(例如 with boost::lexical_cast
),而是转换为正确类型的函数指针并调用函数。如果我允许可能的 8 种类型和最多 8 个参数,那我的代码中已经有很多分支了。我想避免的(伪代码):
开关(md.param_types.size()) { 案例0: 转换函数指针,调用它 休息; 情况1: 开关(md.param_types[0]) { 案例 t_int: int param = boost::lexical_cast(param_strings[0]); 转换函数指针,使用参数调用 案子 ... } 休息; 案例2: 开关(md.param_types[0]){ 案例 t_int: int param = boost::lexical_cast(param_strings[0]); switch (md.param_types[1]) {...} // 第二个参数类型.. } 休息; 案例n... }
随着参数的数量和可能的类型,这很快就会爆炸。我正在寻找一些解决方案(伪代码):
for (auto& p : paramter_strings)
{
convert p to a variable of matching type (type id comes from meta_data).
store value
}
call function with stored values
即函数调用没有分支。如何使用最少的样板代码(可能支持任意数量的参数)来做到这一点?您可以将其视为创建与自定义脚本语言的绑定。