2016-10-26 2 views
3

C++ 11では、関数テンプレートのシーケンスを配列初期化子に明示的にインスタンス化するテンプレートを作成できますか?そのまま上記のコードが動作する 明示的な関数テンプレートインスタンスのシーケンスを作成する

// The template I want to instantiate: 
template<size_t N> void callbackTemplate(const int dummy) { 
    // Do something which needs to know 'N'. 
} 

// The variable I want to assign 'callbackTemplate' instantiations to: 
void (*callback)(const int dummy); // This cannot be std::function, because it 
            // is not defined by me! It is already there and 
            // must be used as it is. 

// This is the set of instantiations I want to prepare: 
std::array<decltype(callback), 3> callbackTemplates = { 
    callbackTemplate<0>, callbackTemplate<1>, callbackTemplate<2> 
}; 

のように私は(私はそれは長い話だから、ということが必要な理由は聞かないでください)達成したいことになります。私が変更したいのは、配列 callbackTemplatesの初期化です。私は、初期化子をコンパイル時定数に依存するテンプレートにして、インスタンス化0..Nを作成します。

問題は何とかC++ static const array initialization in template classに関連していますが、他のテンプレートのインスタンス化を「テンプレート化」することはできませんでした。

+1

は[これ](http://melpon.org/wandbox/permlink/6n2WUv4tG2cW8Udp)は何ですか? – krzaq

+0

[this](http://stackoverflow.com/a/6744787/6387170)help – UKMonkey

+0

これは非常識です!あなたはそれをコード化しましたか? – Christoph

答えて

2

なります。 Hereのものです。

using callback_t = decltype (callback); 

として定義callback_t

あなただけのシーケンスを渡すと、型推論を利用することができます:

template<unsigned... Is> 
array<callback_t, sizeof...(Is)> make_callback_array_impl(seq<Is...>) 
{ 
    return { callbackTemplate<Is>... }; 
} 

template<unsigned N> 
array<callback_t, N> make_callback_array() 
{ 
    return make_callback_array_impl(GenSeq<N>{}); 
} 

live demo

0

次のような意味ですか?

template <std::size_t ...> 
struct range 
{ }; 

template <std::size_t N, std::size_t ... Next> 
struct rangeH 
{ using type = typename rangeH<N-1U, N-1U, Next ... >::type; }; 

template <std::size_t ... Next > 
struct rangeH<0U, Next ... > 
{ using type = range<Next ... >; }; 


template <std::size_t N> 
struct arrayWrapper 
{ 
    private: 
     std::array<decltype(callback), N> callBT; 

     template <std::size_t ... rng> 
     arrayWrapper (const range<rng...> &) 
     : callBT{ callbackTemplate<rng>... } 
     { } 

    public: 
     arrayWrapper() 
     : arrayWrapper (typename rangeH<N>::type()) 
     { } 
}; 

あなたはC++ 14を使用することができる場合、あなたがC++ 14のstd::integer_sequenceの実装を使用してこれを行うことができ、あなたは離れてrangeHrangeを投げることができるし、ラッパーは単に

template <std::size_t N> 
struct arrayWrapper 
{ 
    private: 
     std::array<decltype(callback), N> callBT; 

     template <std::size_t ... rng> 
     arrayWrapper (const std::index_sequence<rng...> &) 
     : callBT{ callbackTemplate<rng>... } 
     { } 

    public: 
     arrayWrapper() 
     : arrayWrapper (std::make_index_sequence<N>()) 
     { } 
}; 
2

これは、可変テンプレート特殊で行うことができます。

template<class> 
int callbackTemplates_v; 

template<std::size_t... Indicies> 
std::array<decltype(callback), sizeof...(Indicies)> 
    callbackTemplates_v<std::index_sequence<Indicies...>> = {callbackTemplate<Indicies>...}; 

template<std::size_t N> 
auto callbackTemplates = callbackTemplates_v<std::make_index_sequence<N>>; 

callbackTemplates<N>0..N-1からcallbackTemplateN instaniationsの配列です。

+0

これはC++ 11の解決策ではないことに注目する価値があります。しかし、とてもいいですね。 – krzaq

+0

いいですね、でもVC2013でコンパイルする必要があります... – Christoph

関連する問題