我试图让编译器推断出正确的函数模板。 给定以下代码,推导出正确的模板化函数...
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 函数。但是,如果我将重载的 F 函数添加到 Test,那么它(使用 2 个参数重载)将被调用(而不是使用 1 个参数的正确 F)
void F( s32 one, s32 two )
{
std::cout << "two";
}
我很确定这是因为编译器没有足够的信息来推断。我如何帮助编译器推断要调用哪个重载模板函数?
类似于下面的伪代码...(?表示一些未知类型的 arg)
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 );
}
}
有办法吗?
最佳答案
编译器无法知道您的变体类中存储了什么。所以 ?
只能从函数类型(从它的参数)中推导出来。因此,您将需要一些代码来检查 args.size()
匹配功能参数的数量。尝试执行以下操作:
- 创建
std::tuple<Args...>
其中Args...
从函数类型评估 - 检查
args.size()
与std::tuple<Args...>
中的元素数量相同 - 转换您的
args
vector 到元组。 - 使用
std::apply
(或重新发明你自己的)用元组中的参数调用你的函数
关于c++ - 将重载函数指针作为参数传递给重载模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47993852/