In Haskell, typeclasses allow for you to elegantly overload functions based on return type. It is trivial to replicate this in C++ for cases where both the arguments and the return type are overloaded, using templates (example A):
template <typename In, typename Out> Out f(In value);
template <typename T> int f<T, int>(T value) {
...
}
Which corresponds to Haskell's:
class F a b where
f :: a -> b
You can even overload just the return type on most functions (example B):
template <typename Out> Out f(SomeClass const &value);
template <> inline int f(SomeClass const &value) {
return value.asInt();
}
template <> inline float f(SomClass const &value) {
return value.asFloat();
}
Which corresponds to something like:
class F a where
f :: SomeData -> a
But what I would like to be able to do is modify this last example to overload on higher-order types, namely templated structs in C++. That is, I'd like to be able to write a specialization akin to the following Haskell:
data Foo a = Foo a
instance F (Foo a) where
f someData = Foo $ ...
How would one go about writing a template with this functionality (is it even possible)?
For reference, I'm intending to use this to write template functions for Lua/C++ bridge. The idea is to bridge between Lua and C++ functions by having an overloaded function interpretValue
that automatically pushes or converts from the Lua stack. For simple types that have a direct built-in Lua representation, this is easy enough using code such as example B.
For more complicated types, I'm also writing a template <typename T> struct Data
to handle memory management for objects (bridging between Lua's GC and a C++ side refcount), and I was hoping to be able to overload interpretValue
so that it can automatically wrap a userdata pointer into a Data<T>
. I tried using the following, but clang gave a "function call is ambiguous" error:
template <typename U> inline U &interpretValue(lua_State *state, int index) {
return Data<U>::storedValueFromLuaStack(state, index);
}
template <typename U> inline Data<U> interpretValue(lua_State *state, int index) {
return Data<U>::fromLuaStack(state, index);
}
Thanks!
template <typename T> Foo<T> f(const SomeClass& value)
not work for you? – Brian Bi