使用C++11实现C++17的apply(动态数组用作函数参数

标题有点错误,apply是用tuple做参数,调用一个函数。这个标题是为了能更好的适配搜索关键字。动态数组用作函数参数更适合嵌入了脚本环境的C++程序,比如lua或javascript(js)。

若有疏忽或改进,请评论,谢谢。

VS2017虽然实现了一些C++17特性,但没有apply(也许我没发现或有替代),而且即使以后更新添加了,也不是很满足我提到的数组转参数列表。

下面是VS2015.3测试通过的代码。

写脚本封装(Wrapper)功能一般都是把C++函数(一般是成员函数)注册到脚本的环境,我看了很多开源作者都重载了很多模板类/模板函数,其实都挺类的,虽然都是一些体力活,但一旦修改就是批量的。

本文参考了stackoverflow的Johannes Schaub的回复,附录有链接。

代码中的intint只是一个自动转换例子而已,什么也没做,你可以替换为你的脚本对象转原生对象的转换器。

代码的核心部分是嵌套的模板类继承,这一段比较烧脑子:

template<int ...>struct seq {}; template<int N, int ...S> struct gen_seq : gen_seq<N - 1, N - 1, S...> {};// 嵌套继承,为了得到一个N-M至N的参数序列,是无限的 template<int ...S> struct gen_seq<1, S...> { typedef seq<S...> type; };// 特例。对上面嵌套继承的一个终止,终止条件是1开始到N

全部代码,无输出,请自行添加,同样,也不需要其它头文件:

struct intint { int i; intint(int i) :i(i) {} operator int() { return i; } }; template<int ...>struct seq {}; template<int N, int ...S> struct gen_seq : gen_seq<N - 1, N - 1, S...> {}; template<int ...S> struct gen_seq<1, S...> { typedef seq<S...> type; }; template<typename T, typename R, typename...TS> struct callable { typename gen_seq<sizeof...(TS)+1>::type fo; R(T::*func)(TS...); callable(R(T::*func)(TS...)) :func(func) {} template<int ...S> void call(seq<S...>, int* v) { (new T->*func)(intint(v[S])...); } void operator()(T*, int* v) { call(fo, v); } }; struct foo { void func(int, int, int, int) { } }; int main() { callable<foo, void, int, int, int, int> c(&foo::func); int v[] = { 100,200,300,400,500,600 }; c(new foo(), v); return 0; }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/fd2fec4b9e2d88533c16085ebb8d68b5.html