A solution that does not require changing your interface is to forward the function call to a template<> class
, where you can specialize to your hearts content:
template<typename R, typename... Ts>
struct DoCallFun {
R operator()( LuaScript* self, std::string const& name, Ts&&... ts ) {
}
};
template <typename Z, typename... T>
Z LuaScript::callFun(const std::string& name, Ts&&... ts) {
return DoCallFun<Z, Ts...>()( this, name, head, std::forward<Ts>(ts)... )
}
and we implement the body of callFun
within DoCallFun
. If it needs access to private variables in LuaScript
we make DoCallFun
a friend
.
Now, a better solution might be to use a "traits class
" for much of the return
-type dependent behavior. If you need to call a different function based on the return
type, instead of writing the same callFun
once for each return
type with a slight difference, you can create a "traits class
" where you isolate the difference based on return
type.
Suppose you need to call int CallAndReturnInt(...)
if the type is int
and double CallAndReturnDouble(...)
if the type is double
. Instead of having two bodies of callFun
, write a traits class:
template<typename T>
struct lua_return_traits;
template<>
struct lua_return_traits<int> {
template<typename... Ts>
static int call_and_return( Ts&&... ts ) {
return CallAndReturnInt( std::forward<Ts>(ts) );
}
};
template<>
struct lua_return_traits<double> {
template<typename... Ts>
static double call_and_return( Ts&&... ts ) {
return CallAndReturnDouble( std::forward<Ts>(ts) );
}
};
and similar techniques for other ways your method should differ based on the return
type.