用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;
}

 

 

 

附:【“unpacking” a tuple to call a matching function pointer


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM