繁体   English   中英

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

[英]Passing a function pointer as non-type template parameter

我有此模板功能,它运行良好:

    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 *作为参数):

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

可行,但对我的目的没有用

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> ,而没有所有额外的噪音。

template<class Fn, class R, class... Args>
R test(Args&&... args) {
  return Fn{}(std::forward<Args>(args)...);
}

int foo( int a, int b ) { return a+b; }

int r = test< constant_t<TYPEDARG(foo)>, int, int, int >( 3, 4 );

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

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地址并传递给我的脚本引擎。 实际上,我宁愿有一个没有宏的解决方案。 仍然欢迎更好的解决方案!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM