2013-03-04 55 views
8

我想創建一個接受可變數量模板參數的函數。後來這些參數的函數應該通過自己的立場是這樣的:傳遞可變參數模板參數的位置

template<typename R, typename Args...> 
R myFunction(Data &data, void *function) { 
    auto f = (R (*)(Args...))function; 
    return f(read<Args1>(data, 1), read<Args2>(data, 2), ...);// <-- This is the problem 
} 

給定的代碼當然不是編譯。有什麼方法可以解決它嗎?有沒有沒有太多代碼重複可變模板的方法?

+2

我相信你可以避免指向函數指針轉換的對象指針。 – sellibitze 2013-03-04 15:18:51

+0

@sellibitze:這是一個問題嗎?因爲我只能有一個從C函數傳遞的void *指針用戶數據。 – 2013-03-04 15:40:05

+0

數據可以是'void *'。這是一個值得關注的「void *」函數。 – 2013-03-04 15:41:27

回答

14

是的,這是可能的:

// 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 packArgssizeof...的大小。 make_indices<N>::type然後擴展爲indices<0,1,2,...,N-1>。它作爲實現函數的附加參數(來自僅創建虛擬實例的轉發器)提供,因此參數推導在實現函數的一側開始,並將生成的索引放入參數包Ns

該實現函數現在有兩個相同大小的參數包,即ArgsNs。當通過省略號...進行擴展時,省略號擴展了的整個表達式它應用於並且它並行擴展所有參數包!在上面的例子中,表達式是read<Args>(Data, Ns+1),很好地擴展到OP僞碼。

+0

你可以發表一個簡單的例子嗎? – 2013-03-04 15:16:22

+2

我剛剛做到了。我給的例子中缺少的是什麼? – 2013-03-04 15:17:41

+0

缺少的是一個真實的例子。用'main()'和一些函數(有1,2,3個參數)。你如何使用這些功能和結構? – 2013-03-04 21:09:11