2014-01-25 147 views
0

我正在採取一種結構,其中包含可變類型,提取它們,並將它們傳遞給本機函數調用 。有效的模板擴展?

//ValueArray contains a vector of a variant type. 

// Pulls out an argument from a ValueArray. 
template<typename Arg> 
inline Arg 
_processParam(ValueArray& args) { 
    Arg arg = static_cast<Arg&>(args[ 0 ]); 
    args.erase(0, true); 
    return arg; 
} 


/// Do the Function call. Args is a variadic template pack. 
call(fnPtr, _processParam<Args>(args)...); 

/// The call expands to: 
(*fnPtr)(params...); 

然而,問題是_processParam(args)...擴展是按照相反的順序通過類型拉出參數。例如,[1,1.4]的ValueArray將作爲double,then和int被拉出。有沒有辦法以便攜的方式正確地提取參數?

+0

評估論證的函數調用的表達式(用','分隔,不是逗號運算符)是*無序的*。對於像g ++這樣的編譯器,順序是從右到左的,即最右邊的參數表達式首先被計算。看起來你的程序有未定義的行爲。 – dyp

+0

大多數編譯器是從右向左還是從左向右評估?如果是這樣,我現在可以處理這些案件。否則有沒有辦法通過函數調用附加索引? – h4tch

回答

1

擺脫erase並添加索引。在進行函數調用時不要改變在其他參數計算中使用的數據,因爲順序未定義(使編譯器可以爲了效率或miin的階段對它們進行重新排序)。

您將需要添加一個間接層做到這一點很容易:

template<unsigned...>struct indexes {}; 

template<unsigned num, unsigned... Is>struct make_indexes: 
    make_indexes<num-1, num-1, Is...>{}; 
template<unsigned...Is>struct make_indexes<0,Is...>:indexes<Is...>{}; 

template<typename... Args, unsigned...Is> 
void do_call(indexes<Is...>, ValArray& arr){ 
    call(fnPtr, ProcessParam<Args>(arr[Is])...); 
} 

其中ProcessParam現在需要一個元素不是一個數組,並用它喜歡:

do_call<Args...>(make_indexes<sizeof...(Args)>(), arr); 
+0

不是這是一個電話答案:可能有typso – Yakk

+0

謝謝,我無法弄清楚如何獲得索引。這看起來像某種zip操作。 – h4tch

+0

@DanH。回答改善。您創建一個相同大小的索引包,然後將它們平行展開。請注意,C++ 1y將具有'index_sequence',它可以處理上面的大部分樣板。 – Yakk