首页 > 解决方案 > 函数中特定行的模板

问题描述

我正在为嵌入式 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;
}

有没有一种方法可以针对单独的代码行专门化一个模板?还是我误解了我应该使用模板做什么?

标签: c++templates

解决方案


如果您的编译器支持 C++17,您可以使用if constexpr

template<typename T>
T LuaManager::GetGlobal(const std::string & name)
{
    lua_getglobal(luaState, name);
    T value;
    if constexpr (std::is_same_v<T, std::string>)
        value = lua_to_string(luaState, -1); // I don't know the actual name of this function
    else if (std::is_same_v<T, int>)
        value = lua_to_int(luaState, -1);
    else if (std::is_same_v<T, whatever>)
        value = lua_to_whatever(luaState, -1);
        // some other arbitrary type dependent code
    else ... // other types 
    lua_pop(luaState, 1);
    return value;
}

注意:要在 Visual Studio 中启用 C++17,请右键单击您的项目并单击属性。然后转到 C/C++ -> 语言 -> C++ 语言标准并选择/std:c++17or /std:c++latest


更新

如果您不能或不想使用 C++17,这是另一种不使用任何“新”功能的方法,即使没有模板:

void get_lua_value(string& value)
{
    value = lua_to_string(luaState, -1);
}

void get_lua_value(int& value)
{
    value = lua_to_int(luaState, -1);
}

为每种类型添加这些重载之一。然后你可以打电话get_lua_value(),重载决议将为你完成这项工作:

template<typename T>
T LuaManager::GetGlobal(const std::string& name)
{
    lua_getglobal(luaState, name);
    T value;
    get_lua_value(value); 
    lua_pop(luaState, 1);
    return value;
}

推荐阅读