Reputation: 240
I'm trying to get the compiler to deduce the correct function template. Given the following code, the correct templated function is deduced...
class TestBase{};
template <typename c, typename RT, typename T0>
inline void CallF( RT( c::*M )(T0), TestBase* pObject, std::vector<OVariant> args )
{
//safely convert variant (implementations external to class)
T0 t0 = args[0].GetSafe<T0>();
((static_cast<c*>(pObject))->*M)(t0);
}
template <typename c, typename RT, typename T0, typename T1>
inline void CallF( RT( c::*M )(T0, T1), TestBase* pObject, std::vector<OVariant> args )
{
//safely convert variant (implementations external to class)
T0 t0 = args[0].GetSafe<T0>();
T1 t1 = args[1].GetSafe<T1>();
((static_cast<c*>(pObject))->*M)(t0, t1);
}
class Test : public TestBase
{
public:
void F( s32 one )
{
std::cout << "one";
}
struct Wrapped_F
{
//OVariant is my typical variant class
static void Call( TestBase* pObject, std::vector<OVariant> args )
{
::CallF<Test>( &Test::F, pObject, args );
}
};
};
int main(int argc, char *argv[])
{
Test t;
OVariant i( 13 );
std::vector<OVariant> args;
args.push_back( i );
t.Wrapped_F::Call( &t, args );
}
t.Wrapped_F::Call( &t, args ) calls the correct F function. However, if I add the overloaded F function to Test, then it (overload with 2 args) will be called (instead of the correct F with 1 arg)
void F( s32 one, s32 two )
{
std::cout << "two";
}
I'm pretty sure this is due to the fact that the compiler does not have enough info to deduce. How can I help the compiler deduce which overloaded template function to call?
Something like the following pseudo code... (? to denote some arg of unknown type)
static void Call( TestBase* pObject, std::vector<OVariant> args )
{
//Note: I won't know anything about the arguments to function F; I do know the size of the vector
switch ( args.size() )
{
case 1:::CallF<Test,void,?>( &Test::F, pObject, args );
case 2:::CallF<Test,void,?,?>( &Test::F, pObject, args );
}
}
Is there a way to do this?
Upvotes: 0
Views: 226
Reputation: 6667
The compiler has no way of knowing what is stored inside your variant class. So the ?
could be deduced only from the function type (from its parameters). Hence, you will need some code to check that args.size()
matches the number of function parameter. Try to do the following:
std::tuple<Args...>
where Args...
are evaluated from the function typeargs.size()
is the same as number of elements in the std::tuple<Args...>
args
vector to the tuple.std::apply
(or re-invent your own) to call your function with arguments from the tupleUpvotes: 1