我正在为嵌入式Lua写包装器,并且我有一系列函数从lua_State检索全局值。由于该函数对每个函数几乎执行完全相同的操作(使用lua_getglobal(L, name)
获取全局名称,调用适当的lua_to___()
函数,然后弹出堆栈以将lua_State返回其原始状态),我认为应该有某种方法可以执行此操作与模板。
但是,我似乎无法找到一种方法来让一条重要的行依赖于类型,而不必为每种类型编写完全独立的函数,而该行对类型至关重要。虽然目前此功能只有三行,但还有其他类似功能可能更复杂但存在相同问题。
到目前为止,函数看起来像这样(这在名为LuaManager的类中,该类具有lua_State *成员):
//Declaration
template<std::string>
std::string GetGlobal(const std::string & name);
template<int>
int GetGlobal(const std::string & name);
template<float>
float GetGlobal(const std::string & name);
template<bool>
bool GetGlobal(const std::string & name);
//Implementation
template<typename T>
T LuaManager::GetGlobal(const std::string & name)
{
lua_getglobal(luaState, name.c_str()); //push the global to the top of the stack
T value = lua_to____(luaState, -1); //store the value for return
lua_pop(luaState, 1); //return the stack to empty
return value;
}
有没有一种方法可以针对单个代码行专门化模板?还是我误解了我应该为模板使用什么?
最佳答案
声明应该只是:
template<class T>
T GetGlobal(const std::string& name);
对于实现,我将创建一个结构模板,并使用特化作为类型到功能的映射。
#include <type_traits>
template<class>
struct lua_to;
template<>
struct lua_to<int> {
typedef int(*type)(decltype(luaState), int);
static constexpr const type value = lua_to_int;
};
template<>
struct lua_to<std::string> {
typedef std::string(*type)(decltype(luaState), int);
static constexpr const type value = lua_to_string;
};
// In this case, since this is so tedious, I would use a macro
#define MY_MODULE_DEFINE_LUA_TO(ctype, luatype) \
template<> \
struct lua_to<ctype> { \
typedef ctype(*type)(decltype(luaState), int); \
static constexpr const type value = lua_to_ ## luatype; \
};
MY_MODULE_DEFINE_LUA_TO(std::map, table);
MY_MODULE_DEFINE_LUA_TO(double, float);
#undef MY_MODULE_DEFINE_LUA_TO
template<class T>
T GetGlobal(const std::string& name) {
lua_getglobal(luaState, name); //push the global to the top of the stack
T value = lua_to<T>::value(luaState, -1); //store the value for return
lua_pop(luaState, 1); //return the stack to empty
return value;
}
关于c++ - 在功能中对特定行进行模板化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53853193/