mardi 27 septembre 2016

Template specialization for classes which have a certain method

I have a templated method of a Lua State class, which tests if the object at a given index is of a given type:

template<typename T> bool is(int idx) {
    return luaL_testudata(L, idx, std::remove_pointer<T>::type::name) != NULL;
};

and a few specializations:

template<> inline bool State::is<bool>(int i){ return lua_isboolean(this->L, i); }
template<> inline bool State::is<int>(int i){ return lua_isinteger(this->L, i); }
//etc...

Now I want to add a specialization for any class that has a static "lua_test" method:

template<> inline bool State::is<T>(int i){ return T::lua_test(this->L, i); }

But I don't know the correct syntax for this. The closest I've come is:

template <class T>
inline auto State::is(int idx) ->
decltype(std::declval<T>.lua_test(this, idx), true)
{
    return T::lua_test(this, idx);
}

This fails to compile, because apparently the types don't match:

templates.hpp:87:13: error: prototype for ‘decltype ((declval<T>.lua_test(((Lua::State*)this), idx), true)) Lua::State::is(int)’ does not match any in class ‘Lua::State’
 inline auto State::is(int idx) ->
             ^~~~~
In file included from [...],
                 from debug.cpp:1:
get.hpp:6:27: error: candidate is: template<class T> bool Lua::State::is(int)
 template<typename T> bool is(int idx) {

The idea is supposed to be that the decltype statement evaluates to decltype(true) (due to the comma operator), ie bool, but gcc doesn't seem convinced of this.

This seems like it should be pretty simple, but I've been getting nowhere trying to implement it.

Aucun commentaire:

Enregistrer un commentaire