c++ - 函数中特定行的模板
问题描述
我正在为嵌入式 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++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++17
or /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;
}
推荐阅读
- c# - Xamarin .NET API 使用 Refit 错误 Refit.ApiException
- asp.net-core - Visual Studio 2019 QuickWatch 在 ASP.NET Core Blazor WebAssembly Program.cs 文件中显示无法评估(Unable to evaluate)
- python - 从网页抓取时出现 IndexError
- python - 如何使用 django-two-factor-auth 在 django 中为现有用户获取 OTP 令牌
- javascript - UnhandledPromiseRejectionWarning: RangeError [EMBED_FIELD_VALUE]: MessageEmbed 字段值不能为空
- android - RxBLELibraries/RxAndroidBle:状态为 8(GATT_INSUF_AUTHORIZATION 或 GATT_CONN_TIMEOUT)
- angular - 拖动事件触发了几秒钟
- c# - meshbuilder AddPolygon() 方法的奇怪行为的原因是什么?
- automation - 如何从空手道 API 自动化中的功能文件中验证针对多个数据库实例的 API 响应?
- server - Recaptcha 将 Formmail 的“电子邮件”(发件人)字段替换为我的服务器地址。如果没有 Recaptcha,From 字段可以正常工作。为什么?