您的位置:首页 > 移动开发

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

2017-03-12 18:06 369 查看
标题有点错误,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;
}


附:【“unpacking” a tuple to call a matching function pointer
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐