使用函数指针自动填充 std::map
Automatic population of std::map with function pointers
我正在开发一种C++脚本语言,它使用解释器中"内置"的函数。我使用以下构造将函数名称映射到它们各自的指针:
typedef void(*BuiltInFunction)(Context*);
typedef std::unordered_map<std::string, BuiltInFunction> BuiltinFunctionsMap;
其中Context
是自定义类。
然后我有这样的函数声明:
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);
...
}
最后是一个用实际指针填充地图的例程:
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;
}
我要问的是,是否有办法使用模板或类似的东西从函数声明自动生成人口函数。目前,我正在使用正则表达式,它非常简单,但是每当我添加新函数时我都必须这样做,而且很麻烦。
我不知道
这是否真的是一个有用的答案,但是您可以使用预处理器做一些非常松鼠的事情:
#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's 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 << "foon";
}
void _f_bar_print(Context *context) {
std::cout << "barn";
}
void _f_baz_print(Context *context) {
std::cout << "bazn";
}
}
这种方法的好处是自动生成字符串"foo"
并将其绑定到_f_foo_print
函数。 缺点是可怕的预处理器技巧,以及您仍然必须在两个地方处理foo
的事实。
您可以使用模板元编程自动检测某些类型的函数 - 例如,给定类型 T,您可以以编程方式回答问题"T 有operator+
吗?但在一般情况下,你不能在语言中自动执行上述操作。
相关文章:
- 如何用文本填充 std::vector<int64_t>
- 用原始数据填充 std::vector
- 给定一个填充无符号字符**的 C 函数,如何在没有中间副本的情况下用数据填充 std::vector
- 直接从 C API 填充 std::string
- 用常量值填充 std::vector<double>
- 在成员初始化列表中填充 std::array
- 可以使用 memset 来填充 std::complex<float>s 数组吗?
- 填充 std::d eque<std::vector<std::string>> with boost::assign::list_of
- 清除并重新填充 std::vector<std::vector<T>>导致分配问题
- 用类的第一个条目填充std::向量的首选方法
- 使用函数指针自动填充 std::map
- 如何从缓冲区及其大小填充std::向量
- 可以直接用get_line填充std::vector<std::string>
- 使用boost::bind()填充std::min_element()的自定义函数中的结构
- 填充 std::map 时"C2593: operator = is ambiguous"
- 在填充std::矢量时使用不同的地址
- 为什么从std::string的initializer列表中填充std::向量不会调用std::字符串构造函数
- 在编译时填充 std::数组,并使用 const_cast 填充可能的未定义行为
- 用异构boost::融合向量类型数据填充std::vector
- c++使用' .reserve() '填充' std::vector '作为防止多线程缓存无效和错误共享的一种方