C++ 在编译时动态创建映射
我正在游戏引擎中实现Lua。导出到Lua的所有函数的标题都以C++ 在编译时动态创建映射,c++,template-meta-programming,compile-time,C++,Template Meta Programming,Compile Time,我正在游戏引擎中实现Lua。导出到Lua的所有函数的标题都以luavoid、luaint或luabool开头,以便快速参考预期参数,因此我一眼就能看出该函数正在导出 #define luavoid(...) void luavoid(std::string s) TextMsg() { std::string s; ExtractLuaParams(1, s); ::TextMsg(s.c_str()); } 要将函数实际导出到Lua,需要将它们添加到字典中。启动时,
luavoid
、luaint
或luabool
开头,以便快速参考预期参数,因此我一眼就能看出该函数正在导出
#define luavoid(...) void
luavoid(std::string s) TextMsg()
{
std::string s;
ExtractLuaParams(1, s);
::TextMsg(s.c_str());
}
要将函数实际导出到Lua,需要将它们添加到字典中。启动时,映射用于调用lua\u寄存器
std::unordered_map<std::string, ScriptCall> _callMap = {
{ "TextMsg", TextMsg },
...
}
它起作用了
我的问题是,这有多可怕,可以改进吗?最后我想要的是一个将字符串映射到函数的列表。有没有更好的方法来创建映射,或者我应该使用文本解析方法
温柔一点。这是我第一次尝试用这样的模板编码。我假设这属于模板元编程
这有多可怕,可以改进吗
在可怕和可怕之间。(有些问题最好不要问。)是的
最后我想要的是一个将字符串映射到函数的列表。有没有更好的方法来创建映射,或者我应该使用文本解析方法
最简单的做法是:
#define ADDFN(FN) { #FN, FN }
std::unordered_map<std::string, ScriptCall> _callMap = {
ADDFN(TextMsg),
...
};
看到它在运行
这里的想法是宏生成一个函数声明,以便它可以注册函数,然后再注册一个定义<代码>\uuuuu行\uuuuu可能足以满足标识符的唯一性—假设您有一个文件来执行此操作,并且您的编译器替换了一个数字文本(我使用的所有编译器都是这样做的,但我不记得标准是否要求这样做)。emplace
函数具有非void
返回类型,因此可以直接用于插入到映射中
温柔一点。这是我第一次尝试用这样的模板编码
对不起
我假设这属于模板元编程
这是有争议的。许多C++程序员(我自己)认为“元编程”涉及更高级的模板使用——例如参数的可变长度列表、递归实例化和专业化——但是许多其他人认为模板的使用都是“元编程”,因为模板提供了如何创建实例的说明,这是技术上足以构成的。我试图解释如何对不熟悉C++的人工作,并开始重新思考。它会失败,因为没有函数声明。然后我读了你的回复,我也走上了同样的道路。耶!我应该提到,我希望函数定义跟随添加到映射中,但你理解我的想法。完美的作为记录,我总是批评我自己的代码,所以诚实值得赞赏。我会在一天左右的时间里把它标记为已回答。
#define ADDFN(FN) { #FN, FN }
std::unordered_map<std::string, ScriptCall> _callMap = {
ADDFN(TextMsg),
...
};
#define LUAVOID(FN, ...) \
void FN(); \
static auto addFN ## __LINE__ = myMap.emplace(#FN, FN); \
void FN()
LUAVOID(TextMsg, string s)
{
...
}