如何编写 Lua 包装,使用一个可能返回多个类型的方法从栈中返回一个值?

有人能解释一下为什么下面的代码不起作用,并提出建议,以使其起作用。 如果可能的话,我愿意不使用 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);
}

错误消息的一部分:

从中无法将“lua_Integer”(又名“long”)转换为“std :: basic_string <char>”的适当转换
    返回lua_tointeger(lua,stackPos);
          ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/lua.h:320:28:注意,从宏'luate')扩展了
#define lua_tointeger(L,i)    lua_tointegerx(L,i,NULL)
                            ^~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:20:15:注意,在此处请求函数模板专业化'cppLua :: luaStackItem :: getAs <std :: basic_string <char>> '
cout << I.getAs<std::string>() << endl;
点赞
用户869951
用户869951

模板是编译时概念,不是运行时概念。二进制文件中没有模板代码。因此,你的 getAs 无法编译:有时你不能返回一种类型,有时你又返回另一种类型。不过,你可以这样做:

// 定义通用模板:
template <typename T> T getAs();

// 为不同返回类型定义特化:
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 的模板实例,在源代码中使用过的实例。

2014-06-17 00:23:13