【问题标题】:Transform variadic template parameters to another types将可变参数模板参数转换为其他类型
【发布时间】:2011-07-11 06:02:42
【问题描述】:

如何将可变参数模板参数的类型转换为另一种类型?

例如:

template <typename... T>
struct single
{
   std::tuple<T...> m_single;
};

template <typename... T>
struct sequences
{
   single<T...> get(size_t pos)
   {
       // I don't know how to convert here
       return std::make_tuple(std::get<0>(m_sequences)[pos]... std::get<N>(m_sequences)[pos]);
   }

   template <size_t Idx>
   std::vector<
      typename std::tuple_element<Idx, std::tuple<T...>>::type
      >
   get_sequence()
   {
      return std::get<Idx>(m_sequences);
   }

   std::tuple<T...> m_sequences; // std::tuple<std::vector<T...>> I don't know how to conver here
};

我想这样写:

sequences<int, double, double> seq;
single<int, double, double> sin = seq.get(10);

并且在结构序列中有std::tuple&lt;std::vector&lt;int&gt;, std::vector&lt;double&gt;, std::vector&lt;double&gt;&gt;。并从中获得单身。

std::vector&lt;single&lt;T...&gt;&gt; 对我来说是个坏主意,因为我需要一个完整的序列并且很容易从中复制它。

有可能吗?

非常感谢。对不起我的英语不好。

【问题讨论】:

    标签: c++ c++11 tuples variadic-templates


    【解决方案1】:

    您可以做的不仅仅是将可变参数包扩展为普通列表:您还可以扩展表达式。因此,您可以让 m_sequences 成为向量元组而不是元素元组:

    template <typename... T>
    struct sequences
    {
       std::tuple<std::vector<T>...> m_sequences;
    };
    

    您还可以使用参数包做一些漂亮的技巧来从向量中选择适当的元素:

    template<size_t ... Indices> struct indices_holder
    {};
    
    template<size_t index_to_add,typename Indices=indices_holder<> >
    struct make_indices_impl;
    
    template<size_t index_to_add,size_t...existing_indices>
    struct make_indices_impl<index_to_add,indices_holder<existing_indices...> >
    {
        typedef typename make_indices_impl<
            index_to_add-1,
            indices_holder<index_to_add-1,existing_indices...> >::type type;
    };
    
    template<size_t... existing_indices>
    struct make_indices_impl<0,indices_holder<existing_indices...> >
    {
        typedef indices_holder<existing_indices...>  type;
    };
    
    template<size_t max_index>
    typename make_indices_impl<max_index>::type make_indices()
    {
        return typename make_indices_impl<max_index>::type();
    }
    
    
    
    template <typename... T>
    struct sequences
    {
        std::tuple<std::vector<T>...> m_sequences;
    
        template<size_t... Indices>
        std::tuple<T...> get_impl(size_t pos,indices_holder<Indices...>)
        {
            return std::make_tuple(std::get<Indices>(m_sequences)[pos]...);
        }
    
        std::tuple<T...> get(size_t pos)
        {
            return get_impl(pos,make_indices<sizeof...(T)>());
        }
    };
    

    【讨论】:

      【解决方案2】:

      好的,这可能看起来有点矫枉过正,但如何:据我所知,“迭代”可变参数的唯一选择是使用 &lt;head, tail...&gt; 表示法和简单的 &lt;head-only&gt; 案例的模板特化。

      因此你可以尝试这样的事情:

      简单案例:

      template <typename T>
      struct sequences
      {
         std::tuple<T> get(size_t pos)
         {
           return values[pos];
         }
      
         std::vector<T> get_sequence()
         {
            return values;
         }
      
         std::vector<T> values;
      };
      

      递归案例:

      template <typename T, typename ...U>
      struct sequences
      {
         std::tuple<T, std::tuple<U...> > get(size_t pos)
         {
           return std::make_tuple(values[pos], remainder->get(pos));
         }
      
        template <size_t Idx>
        std::vector<
            typename std::tuple_element<Idx, std::tuple<T...>>::type
          > get_sequence()
        {
          return get_sequence_internal<
               typename std::tuple_element<Idx, std::tuple<T...>>::type, Idx
             >();
         }
      
         template <typename V, 0>
         std::vector<V> get_sequence_internal()
         {
            return values;
         }
      
         template <typename V, size_t Idx>
         std::vector<V> get_sequence()
         {
            return remainder->getSequence_internal<V, Idx-1>();
         }
      
      
      
         std::vector<T> values;
         sequences<U...>* remainder;
      };
      

      免责声明:未经测试,甚至未经编译,但我想您已了解基本概念。至少还有两个问题:

      1. get() 的返回值不是你的单个结构,而是一个元组链。也许您可以使用std::get&lt;0&gt; 递归地解开它...
      2. 我不知道get_sequence_internal 的特化是否会产生编译时错误,因为V 的类型可能与T 不同。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-07
        • 1970-01-01
        • 1970-01-01
        • 2014-11-06
        • 2014-04-30
        相关资源
        最近更新 更多