Reputation: 15313
I have a generic function for pushing stuff on to the lua stack called luaU_push, which must be specialized for any type that wants to use it. For example:
template <>
inline void luaU_push<>(lua_State* L, const Vector2i& val)
{
lua_newtable(L);
luaU_setfield<int>(L, -1, "x", val.x);
luaU_setfield<int>(L, -1, "y", val.y);
}
It turns out that Vector2i
is actually a typedef. The real type is Vector2<int>
. In a few other places I use Vector2f
s, which are just a typedef for Vector2<float>
.
I'd like to be able to have a luaU_push for Vector2f
s. I could make a duplicate function for Vector2f, but I'd prefer to make this one generic so I can use it on any kind of Vector2<T>
, but I can't figure out the syntax to do that. I thought that I could do something like this, but this does not appear to work:
template <>
template <typename T>
inline void luaU_push<>(lua_State* L, const sf::Vector2<T>& val)
{
lua_newtable(L);
luaU_setfield<T>(L, -1, "x", val.x);
luaU_setfield<T>(L, -1, "y", val.y);
}
Is there a way to get this working the way I want?
Edit:
Follow up question: I had intended to use the answer to this question to fix a set of functions, including a few that only differ by return type, but I don't think the answer given is sufficient for this. For example, I have this function (which is basically the opposite of the function above)
template <>
inline sf::Vector2i luaU_to<>(lua_State* L, int index)
{
return sf::Vector2i(
luaU_getfield<int>(L, index, "x"),
luaU_getfield<int>(L, index, "y"));
}
I don't believe that there's a way to use overloading to make this work in a generic way, and I can't use partial specialization. Is there any way to make it work in this case?
Upvotes: 0
Views: 203
Reputation: 6901
Take this answer as a COMMENT.
template < typename T >
inline void luaU_push(lua_State* L, const sf::Vector2<T>& val)
{
lua_newtable(L);
luaU_setfield<T>(L, -1, "x", val.x);
luaU_setfield<T>(L, -1, "y", val.y);
}
This should work. And in case of templated functions, a "base template" function will always have higher priority than a fully specialized one.
EDIT ::
You have overloaded the function "luaU_to" based upon the return type ! Which is not allowed and possible (unless you use some un-understandable/untidy nasty trick)
What you can do is, create a specialized version for each return data type and dont let compiler do the argument deduction for i.e mention the data type explicitly in the template call.
Upvotes: 2
Reputation: 20238
For your follow-up question:
as ArunMu noted above, it's illegal to overload a function or to specialize a template on the return type only.
What you could do instead is something like this:
class LuaCheck {
public:
LuaCheck (lua_State* L, int index)
: L_(L), index_ (index)
{ }
operator int () { return luaL_checkinteger(L_, index_); } // (a)
operator double () { return luaL_checknumber(L_, index_); } // (b)
private:
lua_State* L_;
int index_;
};
int main () {
lua_State * L = ...;
int index = ...;
int a = LuaCheck (L, index); // will call (a)
double b = LuaCheck (L, index); // will call (b)
}
Upvotes: 1