#include <utility>
#include <stdio.h>
template <typename R, typename... Args>
struct Helper {
template <R (*Func) (Args...)>
struct Wrapper {
static R call (Args&&... args)
{
return Func(std::forward<Args>(args)...);
}
};
};
template <typename R, typename... Args>
struct Helper<R, Args...> MakeHelper (R (*func) (Args...));
#define WRAP_FUNC(func) decltype(MakeHelper(func))::Wrapper<func>
#define WRAP_FUNC_T(func) typename decltype(MakeHelper(func))::template Wrapper<func>
static double test_func (int x)
{
return x;
}
using TestFunc = WRAP_FUNC(test_func);
template <typename Func>
static void CallFunc ()
{
int x = 4;
double r = Func::call(x);
printf("%f\n", r);
}
int main ()
{
CallFunc<TestFunc>();
}
I2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDxzdGRpby5oPgoKdGVtcGxhdGUgPHR5cGVuYW1lIFIsIHR5cGVuYW1lLi4uIEFyZ3M+CnN0cnVjdCBIZWxwZXIgewogICAgdGVtcGxhdGUgPFIgKCpGdW5jKSAoQXJncy4uLik+CiAgICBzdHJ1Y3QgV3JhcHBlciB7CiAgICAgICAgc3RhdGljIFIgY2FsbCAoQXJncyYmLi4uIGFyZ3MpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gRnVuYyhzdGQ6OmZvcndhcmQ8QXJncz4oYXJncykuLi4pOwogICAgICAgIH0KICAgIH07Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgUiwgdHlwZW5hbWUuLi4gQXJncz4Kc3RydWN0IEhlbHBlcjxSLCBBcmdzLi4uPiBNYWtlSGVscGVyIChSICgqZnVuYykgKEFyZ3MuLi4pKTsKCiNkZWZpbmUgV1JBUF9GVU5DKGZ1bmMpIGRlY2x0eXBlKE1ha2VIZWxwZXIoZnVuYykpOjpXcmFwcGVyPGZ1bmM+CiNkZWZpbmUgV1JBUF9GVU5DX1QoZnVuYykgdHlwZW5hbWUgZGVjbHR5cGUoTWFrZUhlbHBlcihmdW5jKSk6OnRlbXBsYXRlIFdyYXBwZXI8ZnVuYz4KCnN0YXRpYyBkb3VibGUgdGVzdF9mdW5jIChpbnQgeCkKewogICAgcmV0dXJuIHg7Cn0KdXNpbmcgVGVzdEZ1bmMgPSBXUkFQX0ZVTkModGVzdF9mdW5jKTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBGdW5jPgpzdGF0aWMgdm9pZCBDYWxsRnVuYyAoKQp7CiAgICBpbnQgeCA9IDQ7CiAgICBkb3VibGUgciA9IEZ1bmM6OmNhbGwoeCk7CiAgICBwcmludGYoIiVmXG4iLCByKTsKfQoKaW50IG1haW4gKCkKewogICAgQ2FsbEZ1bmM8VGVzdEZ1bmM+KCk7Cn0K
prog.cpp: In instantiation of ‘void CallFunc() [with Func = Helper<double, int>::Wrapper<test_func>]’:
prog.cpp:37:24: required from here
prog.cpp:31:28: error: cannot bind ‘int’ lvalue to ‘int&&’
double r = Func::call(x);
^
prog.cpp:8:18: error: initializing argument 1 of ‘static R Helper<R, Args>::Wrapper<Func>::call(Args&& ...) [with R (* Func)(Args ...) = test_func; R = double; Args = {int}]’
static R call (Args&&... args)
^