将函数指针作为非类型模板参数传递

时间:2017-11-14 00:20:33

标签: c++ templates function-pointers

我有这个模板功能,效果很好:

    template<typename RES, typename... PARMS> SQInteger GlobalBind(RES(*fn)(PARMS... parms), const char *sqName, HSQUIRRELVM v)

这就是这样称呼的:

GlobalBind(aFunction, "aName", vm);

它的范围是绑定函数fn到脚本引擎。

以这种方式使用它,我必须将fn指针和代理模板指针保留在脚本引擎内;使用fn作为参数调用代理模板(此处未显示),执行一些操作,然后调用fn

我想要实现的是从函数调用中删除fn指针,并将其作为参数放入模板中,如下所示:

template<typename RES, typename... PARMS, RES(*fn)(PARMS...)> SQInteger GlobalBind(const char *sqName, HSQUIRRELVM v)

因此,为每个不同的fn实例化一个特定的模板,这意味着我可以避免脚本语言中的fn指针;电话应该是:

GlobalBind<aFunction>("aName", vm);

编译器接受模板声明,但调用带来错误,甚至在aFunction之前添加参数类型,如此(假设aFunction返回int并且const char * 1}}作为参数):

GlobalBind<int, const char *, aFunction>("aName", vm);

有没有办法实现这个结果(前者,没有参数列表)?

编辑: 简化问题,是模板

template<typename RES, typename... PARMS, RES(*fn)(PARMS...)> RES TEST(PARMS... parms) {
    return fn(parms...);
}

有效的吗?如果是的话...该怎么称呼? 我试过这个:

int testfn(const char *s) { return strlen(s); }
TEST<testfn>("aString");   << ERROR
TEST<int, const char *, testfn>("aString");  << ERROR

EDIT2: 这一个:

template<int (*fn)(const char *)> int TEST2(const char *s) {
    return fn(s);
}
TEST2<testfn>("aString");

有效,但对我的目的没有用

2 个答案:

答案 0 :(得分:3)

$('#diary').bind('input propertychange', function() {
    $.ajax({
    method: "POST",
    url: "updatedatabase.php",
    data: { content: $("#diary").val() }
    })
        .done(function( msg ) {
        alert( "Data Saved: " + msg );
    });
});

现在template<class T, T t> struct constant_t:std::integral_constant<T,t>{ constexpr operator T()const { return t; } constexpr constant_t(){} }; #define TYPEDARG(...) \ typename std::decay<decltype(__VA_ARGS__)>::type, \ __VA_ARGS__ 是一种类型,如果constant_t<TYPEDARG(foo)>是非重载函数并且它们调用foo,则可以调用其实例。

中,这变为:

foo

并且使用只是template<auto x> using constant_t=std::integral_constant<std::decay_t<decltype(x)>,x>; ,没有任何额外的噪音。

constant_t<foo>

答案 1 :(得分:0)

找到一个(丑陋的)解决方案,但它也适用于重载函数:

int myFunc(const char *s) {
    return strlen(s);
}

const char *myFunc(int i) {
    return "it's me";
}

template<typename FN, FN fn, typename RES, typename... PARMS> RES _DISPATCH(PARMS... parms) {
    return fn(parms...);
}

#define DISPATCH(RES, FN, ...) _DISPATCH<RES(*)(__VA_ARGS__), FN, RES, __VA_ARGS__>

Cout() << (void *)DISPATCH(int, myFunc, const char *) << "\n";
Cout() << (void *)DISPATCH(const char *, myFunc, int) << "\n";

DISPATCH()宏构建一个调度程序,我可以从中获取C地址并传递给我的脚本引擎。 我确实想要一个没有宏的解决方案。仍然愿意接受更好的解决方案!