将重载的函数指针作为参数传递给重载的模板函数

时间:2017-12-27 14:26:39

标签: c++ templates overloading argument-deduction

我试图让编译器推断出正确的函数模板。 给定以下代码,推导出正确的模板化函数......

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 );
}

W.Wrapped_F :: Call(&amp; t,args)调用正确的F函数。但是,如果我将重载的F函数添加到Test中,那么将调用它(带2个args的重载)(而不是带有1个arg的正确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 );
    }
}

有办法做到这一点吗?

1 个答案:

答案 0 :(得分:1)

编译器无法知道变体类中存储的内容。因此,?可以从函数类型(来自其参数)推断。因此,您需要一些代码来检查args.size()是否与函数参数的数量匹配。尝试执行以下操作:

  • 创建std::tuple<Args...>,其中Args...从功能类型
  • 进行评估
  • 检查args.size()是否与std::tuple<Args...>
  • 中的元素数量相同
  • args向量转换为元组。
  • 使用std::apply(或重新创建自己的)来使用元组中的参数调用函数