標題有點錯誤,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; }