Я пытаюсь заставить компилятор вывести правильный шаблон функции. Учитывая следующий код, выводится правильная шаблонная функция...
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 ) вызывает правильную F-функцию. Однако, если я добавлю в Test перегруженную функцию F, то она (перегрузка с 2 аргументами) будет вызвана (вместо правильной F с 1 аргументом)
void F( s32 one, s32 two )
{
std::cout << "two";
}
Я почти уверен, что это связано с тем, что у компилятора недостаточно информации для вывода. Как я могу помочь компилятору определить, какую перегруженную функцию шаблона вызывать?
Что-то вроде следующего псевдокода... (? для обозначения некоторого аргумента неизвестного типа)
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 );
}
}
Есть ли способ сделать это?