首页 > 解决方案 > 给定可变整数列表生成类模板的元组

问题描述

我需要生成一个给定整数列表作为可变参数的类模板元组。我想要达到的结果在下面的示例中给出,但没有编译:

template <unsigned int First, unsigned int... Is>
using remove_first = std::integer_sequence<unsigned int, Is...>;

template <unsigned int... Is, unsigned int Last> // Invalid
using remove_last = std::integer_sequence<unsigned int, Is...>;

template <unsigned int N_prev, unsigned int N>
class A
{};

template <unsigned int... Is>
class B
{
    std::tuple<A<remove_last<Is>, remove_first<Is>>...> object;
};

int main()
{
    B<3, 4, 6, 2> b; // <<= b.object is of type: std::tuple<A<3,4>, A<4,6>, A<6,2>>
}

是否有可能以类似的方式实现?

标签: c++templatestuplesvariadic-templates

解决方案


首先 - 一般来说,可变参数包必须在最后 - 所以这不会编译:

template <unsigned int... Is, unsigned int Last> // Invalid
using remove_last = std::integer_sequence<unsigned int, Is...>;

但是您不需要 remove_first 或 remove_last。您需要将这些对A<_, _>一一存储在帮助模板的内部模板中。当我想在这个玩具项目中实现平面联合时,我发明了(当然,我不知道我是第一个)这种技术。

所以这里有注释的代码:

#include <tuple>
#include <type_traits>

template <unsigned int N_prev, unsigned int N>
class A
{};

// The helper type
template <unsigned int... Is>
struct DefineAPairs;

template <unsigned int I1, unsigned I2, unsigned int... Is>
struct DefineAPairs<I1, I2, Is...>
{
    // in the following line pair A<I1, I2> is added at the proper
    // position in nested DefineAPairs
    template <typename ...FirstPairs>
    using type = typename DefineAPairs<I2, Is...>
          ::template type<FirstPairs..., A<I1, I2>>; 
    //                              here ^^^^^^^^^
  
};

template <unsigned int I1, unsigned I2>
struct DefineAPairs<I1, I2>
{
    // this is sentinel implementation
    template <typename ...FirstPairs>
    using type = std::tuple<FirstPairs..., A<I1, I2>>; 
};


template <unsigned int... Is>
class B
{
public:
    using type = typename DefineAPairs<Is...>::template type<>; 
    type object;
};


int main()
{
    B<3, 4, 6, 2> b; // <<= b.object is of type: std::tuple<A<3,4>, A<4,6>, A<6,2>>
    // the proof it works
    static_assert(std::is_same<std::tuple<A<3,4>, A<4,6>, A<6,2>>,
                               decltype(b.object)>::value);
}

演示


推荐阅读