完美转发到函数指针调用

时间:2017-03-09 22:53:09

标签: c++

我试图在Visual Studio 2015中编译简单的寺庙化包装

template<typename Rv, typename ...Args>
Rv call(Rv(*fp)(Args...), Args&&...args) {
    return (*fp)(std::forward<Args>(args)...);
}

int iArg;
void(*fn)(int);
call(fn, iArg);`

我收到以下编译错误:

test.cpp(30): error C2672: 'call': no matching overloaded function found
error C2782: 'Rv call(Rv (__cdecl *)(Args...),Args &&...)': template parameter 'Args' is ambiguous
1>         test.cpp(22): note: see declaration of 'call'
1>         test.cpp(30): note: could be 'int'
1>         test.cpp(30): note: or       'int&'

为什么?

提前致谢

2 个答案:

答案 0 :(得分:4)

你必须拆分args以允许正确扣除:

template<typename Rv, typename ...Args, typename .. Ts >
Rv call(Rv(*fp)(Args...), Ts&&...args) {
    return (*fp)(std::forward<Ts>(args)...);
}

答案 1 :(得分:0)

通过将模板参数设置为函数类型而不是原始函数指针,可以使调用任何类型的可调用事物变得更通用。海湾合作委员会Working example。应该为视觉工作室工作。

#include <iostream>
#include <type_traits>

template<typename Func, typename ...Args>
typename std::result_of<Func(Args...)>::type call(Func fp, Args&&...args) {
    return fp(std::forward<Args>(args)...);
}

void foo(int i) {
    std::cout << i << std::endl;
}

int main() {
    int iArg = 2;
    void(*fn)(int) = foo;
    call(fn, iArg);

    return 0;
}