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

Las*_*öld 7 c++ templates c++14

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

using Tuple = std::tuple<double, double, double, double, int, int, int, int>; // etc..
Run Code Online (Sandbox Code Playgroud)

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

using Tuple = SomeType<4, double, 4, int>::Type; // expands to the above tuple
Run Code Online (Sandbox Code Playgroud)

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

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

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

for*_*818 7

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

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

template <typename T,size_t reps>
struct repeated_type {
    using type = T;
    static const size_t N = reps;
};
Run Code Online (Sandbox Code Playgroud)

用法如下所示:

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);
}
Run Code Online (Sandbox Code Playgroud)

使用 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>() 
                           )
                       );
Run Code Online (Sandbox Code Playgroud)

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

template <typename...repT>
using n_tuple = decltype( 
                    std::tuple_cat( 
                        ( n_tuple_single<repT>() )... 
                    ) 
                );
Run Code Online (Sandbox Code Playgroud)

现场演示

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

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

  • @Lasersköld 不要错过免责声明。这只是我第一次尝试让它以某种方式工作。我稍后可能会用更少递归的东西更新答案 (4认同)