如何迭代参数包并打开参数类型



我有一个可变函数,可以接受任意数量的混合参数:以下代码按预期工作:

template <typename ... Args>
void call_snippet(lua_State *L, const std::string& name, Args... args) {
lua_rawgeti(L, LUA_REGISTRYINDEX, snippets[name]);
int nargs = 0;
for (auto &&x : {args...}) {
lua_pushinteger(L, x);
nargs++;
}
lua_pcall(L, nargs, LUA_MULTRET, 0);
}

但由于它假定所有参数都是CCD_ 1(或可转换为CCD_。我需要一些类似的东西:

template <typename ... Args>
void call_snippet(lua_State *L, const std::string& name, Args... args) {
lua_rawgeti(L, LUA_REGISTRYINDEX, snippets[name]);
int nargs = 0;
for (auto &&x : {args...}) {
switch (typeof(x)) {
case int:
lua_pushinteger(L, x);
nargs++;
break;
case float:
lua_pushnumber(L, x);
nargs++;
break;
case std:string:
lua_pushcstring(L, x.c_str());
nargs++;
break;
case char*:
lua_pushcstring(L, x);
nargs++;
break;
default:
//raise error
;
}
lua_pcall(L, nargs, LUA_MULTRET, 0);
}

我应该如何实际实现上面的伪代码?

您应该能够为调用lua_push...创建函数重载,并使用fold表达式而不是循环。sizeof...运算符可用于确定参数的数量:

void Push(lua_State* l, std::nullptr_t) = delete;
void Push(lua_State* l, std::string const& str)
{
lua_pushcstring(l, str.c_str());
}
void Push(lua_State* l, char const* str)
{
lua_pushcstring(l, str);
}
void Push(lua_State* l, int value)
{
lua_pushinteger(l, value);
}
void Push(lua_State* l, float value)
{
lua_pushnumber(l, value);
}
template <typename ... Args>
void call_snippet(lua_State *L, const std::string& name, Args&&... args) {
lua_rawgeti(L, LUA_REGISTRYINDEX, snippets[name]);
((Push(L, std::forward<Args>(args))), ...);
int nargs = sizeof...(Args);
lua_pcall(L, nargs, LUA_MULTRET, 0);
}

以下完整的例子应该在类似的场景中证明这一点:

#include <iostream>
#include <utility>
void PrintNumber(float f)
{
std::cout << f << "(float)n";
}
void PrintInt(int i)
{
std::cout << i << "(int)n";
}
void PrintCstring(char const* str)
{
std::cout << str << "(char const*)n";
}
void Print(std::nullptr_t) = delete;
void Print(std::string const& str)
{
PrintCstring(str.c_str());
}
void Print(char const* str)
{
PrintCstring(str);
}
void Print(int value)
{
PrintInt(value);
}
void Print(float value)
{
PrintNumber(value);
}
template <typename ... Args>
void PrintArgs(Args&&... args)
{
((Print(std::forward<Args>(args))), ...);
int nargs = sizeof...(Args);
std::cout << "nargs = " << nargs << 'n';
}
int main()
{
PrintArgs("foo", std::string("bar"), 42, 99.9f);
}

注意:您可能需要添加一些重载来解决歧义,例如,当传递99.9而不是99.9f时,因为前者是double,在重载解决过程中会导致歧义。

相关内容

最新更新