Variadic模板函数确定函数指针返回类型

时间:2014-05-28 01:51:47

标签: c++ c++11 function-pointers

我有一个可变参数模板函数,它接受一个间接函数指针(及其参数)并调用它(如下所示)。我想知道如何修改这个函数,以便它可以有正确的返回类型匹配它正在调用的间接函数指针?

typedef UINT(APIENTRY *PFNFOO)(UINT, double);

class Foo
{
public:
    static UINT APIENTRY pfnFoo(UINT x, double y)
    {
        return (UINT)(x*y);
    }
};

template<typename PFN, typename... ARGS>
inline void CallFunc(void* pfn, const ARGS&... args)
{
    reinterpret_cast<PFN>(pfn) (args...);
}

int _tmain(int argc, _TCHAR* argv[])
{
    PFNFOO pfn = &Foo::pfnFoo;

    CallFunc<PFNFOO>(pfn, 100, 0.5f);
    return 0;
}

我尝试了以下内容,但它抱怨error C2782: 'RET CallFunc(RET (__cdecl *)(ARGS...),const ARGS &...)' : template parameter 'ARGS' is ambiguous.我认为我只是错过了正确的语法,所以我很感激这里的帮助。

template<typename PFN, typename RET, typename... ARGS>
inline RET CallFunc(RET(*pfn)(ARGS...), const ARGS&... args)
{
    return reinterpret_cast<PFN>(pfn) (args...);
}

auto x = CallFunc<PFNFOO>(pfn, 100, 0.5f);

2 个答案:

答案 0 :(得分:3)

要允许完全扣除,您可以使用以下内容:(live example

template<typename Ret, typename... Params, typename...Args>
inline Ret CallFunc(Ret(*pfn)(Params...), Args&&... args)
{
    return (*pfn)(std::forward<Args>(args)...);
}

然后叫它:

CallFunc(&Foo::pfnFoo, 100, 0.5f); // float will be converted into double in CallFunc.

答案 1 :(得分:1)

您的函数需要UINTdouble作为参数,而您使用intfloat调用它,因此{{1}的类型之间存在不匹配参数,以及传递给PFNFOO的实际参数。此外,没有必要明确指定函数指针类型,让编译器推导出它。您的模板可以简化为:

CallFunc

用法:

template<typename RET, typename... ARGS>
inline RET CallFunc(RET(*pfn)(ARGS...), ARGS&&... args)
{
    return (*pfn)(std::forward<ARGS>(args)...);
}

如果你想传递CallFunc(&Foo::pfnFoo, 100U, 0.5); int,只需明确指定参数类型。

float

Live demo