标题有点错误,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_seq1,
- N - 1,
- S... > {}; // 嵌套继承,为了得到一个N-M至N的参数序列,是无限的
- template < int...S > struct gen_seq < 1,
- S... > {
- typedef seq 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_seq1,
- N - 1,
- S... > {};
- template < int...S > struct gen_seq < 1,
- S... > {
- typedef seq type;
- };
- template 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, 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() {
- callablevoid,
- int,
- int,
- int,
- int > c( & foo: :func);
- int v[] = {
- 100,
- 200,
- 300,
- 400,
- 500,
- 600
- };
- c(new foo(), v);
- return 0;
- }
附:【】
来源: http://www.cnblogs.com/fyter/p/unpacking_array_to_function_arguments.html