如何使用参数数量定义std::tuple<…>

我需要与在表单上使用(误用)元组的代码进行交互:

using Tuple = std::tuple<double, double, double, double, int, int, int, int>; // etc..

我想知道是否有办法用模板来定义这个元组,而不是在表单中:

using Tuple = SomeType<4, double, 4, int>::Type; // expands to the above tuple

并指定参数的数量而不是指定每种类型。

我宁愿只使用 std libs,但接受 boost。我需要它与 c++14 一起工作。使用宏很容易,但我已经有了一个宏解决方案,我不喜欢在这种代码的代码中使用宏。

上面的元组是一个小例子。实际上,元组要大得多,包含更多的类型和更多的每种类型。

回答

我不知道某些std设施可以直接执行您想要的操作。

棘手的部分是具有混合非类型和类型参数的可变参数模板。这个问题可以通过使用助手来避免:

template <typename T,size_t reps>
struct repeated_type {
    using type = T;
    static const size_t N = reps;
};

用法如下所示:

int main() {
    using two_ints = repeated_type<int,2>;
    using three_doubles = repeated_type<double,3>;
    using my_tuple = n_tuple<two_ints,three_doubles>;
    static_assert(std::is_same<
                         std::tuple<int,int,double,double,double>,
                         my_tuple
                  >::value);
}

使用 astd::index_sequence我们可以得到一个std::tuple<T,T,T,...T>viastd::make_tuple

template <typename T,std::size_t...n>
auto n_tuple_impl(std::index_sequence<n...>){ 
    return std::make_tuple( (n,T{})...); 
}

template <typename repT>
using n_tuple_single = decltype( 
                           n_tuple_impl<typename repT::type>(
                               std::make_index_sequence<repT::N>() 
                           )
                       );

可以通过std::tuple_cat以下方式连接其中的几个:

template <typename...repT>
using n_tuple = decltype( 
                    std::tuple_cat( 
                        ( n_tuple_single<repT>() )... 
                    ) 
                );

现场演示。

在两个地方我需要默认构造。如果需要,这可以通过std::declval. 没有实际创建实例。

对于感兴趣的读者,这里有一个相当混乱的 C++11 实现,它基于递归而不是std::index_sequence折叠表达式来实现相同的效果。

  • @Lasersköld don't miss the disclaimer. This was just my first attempt at getting it to work somehow. I might update the answer later with something that uses less recursion

以上是如何使用参数数量定义std::tuple&lt;…&gt;的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>