编写一个Lua包装器,如何使用可以返回多种类型的方法从堆栈返回一个值

Writing a Lua wrapper, how to return a value from the stack using a method that could return multiple types?

本文关键字:返回 一个 类型 种类 堆栈 方法 包装 Lua 何使用      更新时间:2023-10-16

有人能给我解释一下为什么下面的代码不能工作,并提供一个建议,我可以做些什么来使它工作。我是开放使用Boost,但我宁愿不,如果可能的话。我想从代码中做的事情应该是相当明显的。问题是,我不知道什么类型的方法将返回直到运行时?

template <typename T>
T getAs()
{
  if(typeid(T) == typeid(std::string))
return lua_tostring(lua, stackPos);
  if((typeid(T) == typeid(int)) || (typeid(T) == typeid(long)))
return lua_tointeger(lua, stackPos);
  if((typeid(T) == typeid(float)) || (typeid(T) == typeid(double)))
return lua_tonumber(lua, stackPos);
  if(typeid(T) == typeid(bool))
return lua_toboolean(lua, stackPos);
}

部分错误信息:

In file included from ./luaStackResult.hpp:32:
./luaStackItem.hpp:53:9: error: no viable conversion from 'lua_Integer' (aka 'long') to 'std::basic_string<char>'
    return lua_tointeger(lua, stackPos);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/lua.h:320:28: note: expanded from macro 'lua_tointeger'
#define lua_tointeger(L,i)    lua_tointegerx(L,i,NULL)
                            ^~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:20:15: note: in instantiation of function template specialization 'cppLua::luaStackItem::getAs<std::basic_string<char> >' requested here
cout << I.getAs<std::string>() << endl;

模板是编译时的概念,而不是运行时的概念。二进制文件中没有模板代码。因此,您的geta不能按原样编译:您不能有时返回一个类型,有时返回另一个类型。但是,您可以这样做

// define general template:
template <typename T> T getAs();
// define specializations for different returned types: 
template <> std::string getAs<std::string>() { return lua_tostring(lua, stackPos); }
template <> int         getAs<int>()         { return lua_tointeger(lua, stackPos); }
template <> float       getAs<float>()       { return lua_tonumber(lua, stackPos); }
template <> bool        getAs<bool>()        { return lua_toboolean(lua, stackPos); }

当你这么做的时候

cout << getAs<std::string>() << endl;

编译器将选择正确的专门化。运行时将只包含在源代码中使用的getAs的模板实例化。