2015-06-10 69 views
1

是否有可能以某種方式生成模板參數包?C++ 11生成模板參數

我有下面的代碼工作:

zip<0,1,2>.expand(c); 

我的目標是在編譯時生成列表0,1,2,因爲它是要與可變參數模板中使用,例如:

zip<make_sequence<3>>.expand(c); 

我需要這個在編譯時生成,因爲展開觸發了一些模板化函數,根據圖層/過濾器類型得到優化,所以我可以啓動其他代碼。 這個想法背後的意思是能夠確定編譯時生成的層或過濾器列表,並刪除一些ifs(和其他情況),因爲這將在HPC環境中使用(並且在關鍵路徑中)。

這是這個類(簡體版)中:

template<class... Layer> 
class TRAV{ 
    template <int...CS> struct zip{ 
    static void expand(int c){ 
     constexpr int b = sizeof...(Layers); 
     expand2((TRAV::path<CS,b,typename Layers::MONAD_TYPE>(c),0)...); 
    } 
    template<typename...IS> 
    static void expand2(IS&&...) { 
    } 
}; 
void call(int c){ 
    zip<0,1,2>.expand(c); 
} 
}; 

我也嘗試過解決方案的建議:

Implementation C++14 make_integer_sequence

How do I generate a variadic parameter pack?

但他們沒有爲我工作。我得到這個錯誤:

error: type/value mismatch at argument 1 in template parameter list for >‘template

error: expected a constant of type ‘int’, got ‘make_integer_sequence’

有什麼建議嗎? 非常感謝!

回答

3

你需要一個幫手:

template<int... Seq> 
void call(int c, std::integer_sequence<int, Seq...>){ 
    zip<Seq...>::expand(c); 
} 

void call(int c){ 
    call(c, std::make_integer_sequence<int, 3>()); 
} 
+0

它的工作!非常感謝你 – Alberich2k5

1

除了解決方案,@ T.C。已經顯示,你也可以做一些類似於zip<make_sequence<3>>的工作。它應該是這樣的:

apply_indices<zip<>,std::make_index_sequence<3>> 

這樣一個幫手的實現是:

#include <utility> 

template<typename,typename> struct apply_indices_impl; 

template<typename T,template<T...> class C,T... Ns> 
struct apply_indices_impl<C<>,std::integer_sequence<T,Ns...>> 
{ 
    using type = C<Ns...>; 
}; 

template<typename T,typename I> 
using apply_indices = typename apply_indices_impl<T,I>::type; 

Live example

+0

我喜歡這種方法,不幸的是我不能使用(目前)C++ 14 – Alberich2k5

+0

@ Alberich2k5它應該與C++ 11一起工作,所有你需要的就是'std :: make_index_sequence'的實現。但也可以用C++ 11來完成。我只是在答案中使用了C++ 14,以避免複製粘貼另一種解決方案「std :: integer_sequence」。如果您使用兼容接口,還可以獲得額外的好處:將來可以更輕鬆地切換到C++ 14。 –