是的,這是可能的:
// we need a compile-time helper to generate indices
template< std::size_t... Ns >
struct indices
{
typedef indices< Ns..., sizeof...(Ns) > next;
};
template< std::size_t N >
struct make_indices
{
typedef typename make_indices< N - 1 >::type::next type;
};
template<>
struct make_indices<0>
{
typedef indices<> type;
};
有了這些助手,你需要一個轉發你的功能是這樣的:
template<typename R, typename... Args, std::size_t... Ns>
R myFunctionImpl(void *Data, void *function, indices<Ns...>) {
auto f = (R (*)(Args...))function;
return f(read<Args>(Data, Ns + 1)...);// +1 because indices is zero-based
}
template<typename R, typename... Args>
R myFunction(void *Data, void *function) {
return myFunctionImpl< R, Args... >(Data, function, typename make_indices<sizeof...(Args)>::type());
}
編輯:它是如何工作的?首先,我們確定argument packArgs
到sizeof...
的大小。 make_indices<N>::type
然後擴展爲indices<0,1,2,...,N-1>
。它作爲實現函數的附加參數(來自僅創建虛擬實例的轉發器)提供,因此參數推導在實現函數的一側開始,並將生成的索引放入參數包Ns
。
該實現函數現在有兩個相同大小的參數包,即Args
和Ns
。當通過省略號...
進行擴展時,省略號擴展了的整個表達式它應用於並且它並行擴展所有參數包!在上面的例子中,表達式是read<Args>(Data, Ns+1)
,很好地擴展到OP僞碼。
我相信你可以避免指向函數指針轉換的對象指針。 – sellibitze 2013-03-04 15:18:51
@sellibitze:這是一個問題嗎?因爲我只能有一個從C函數傳遞的void *指針用戶數據。 – 2013-03-04 15:40:05
數據可以是'void *'。這是一個值得關注的「void *」函數。 – 2013-03-04 15:41:27