【问题标题】:Create a sequence of explicit function template instantiations创建一系列显式函数模板实例化
【发布时间】:2016-10-26 14:59:57
【问题描述】:

在 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 有关,但我没有设法“模板化”另一个模板的实例化。

【问题讨论】:

  • this你想要什么?
  • this 有帮助吗
  • 这太疯狂了!你刚刚编码了吗?
  • @Christoph 不,GenSeq 的代码让我有点头晕;)

标签: c++ templates variadic-templates


【解决方案1】:

您可以使用 C++14 的 std::integer_sequence 的实现来做到这一点。 Here的一个。

callback_t定义为

using callback_t = decltype (callback);

你可以只传递一个序列并使用类型推导:

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

【讨论】:

    【解决方案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&lt;N&gt;N0..N-1 实例化的callbackTemplate 的数组。

    【讨论】:

    • 值得注意的是,这不是 C++11 解决方案。不过非常好。
    【解决方案3】:

    你的意思是以下吗?

    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,你可以扔掉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>())
           { }
     };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-15
      • 2011-06-23
      • 2014-02-26
      • 2011-10-07
      • 1970-01-01
      • 2013-02-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多