编译时生成整数序列,其中一个省略

b.b*_*old 6 c++ templates c++11

这里这里的答案几乎是我需要的.但是,我希望能够生成以下序列:

gen_seq<5, 2> // {0, 1, 3, 4}
gen_seq<3, 0> // {1, 2}
// optional behavior that would be useful for me:
gen_seq<4, 4> // {0, 1, 2, 3}
Run Code Online (Sandbox Code Playgroud)

在示例中,我使用gen_seq生成从0到N-1而没有I的序列.这不是强制性的,我也可以使用gen_seq,其中N是序列的长度,I是缺失的索引或其他变体.

我认为大多数问题已在相关问题中得到解答.然而,我无法真正地围绕如何将第二个参数的"保留一个"条件纳入其中.

理想情况下,我希望坚持使用c ++ 11功能并避免使用c ++ 14.但是,使用c ++ 14的优雅且特别易读的元素也可能非常有趣.

Jar*_*d42 8

您可以使用以下内容:

#if 1 // Not in C++11 // make_index_sequence
#include <cstdint>

template <std::size_t...> struct index_sequence {};

template <std::size_t N, std::size_t... Is>
struct make_index_sequence : make_index_sequence<N - 1, N - 1, Is...> {};

template <std::size_t... Is>
struct make_index_sequence<0u, Is...> : index_sequence<Is...> { using type = index_sequence<Is...>; };

#endif // make_index_sequence

namespace detail
{
    template <typename Seq1, std::size_t Offset, typename Seq2> struct concat_seq;

    template <std::size_t ... Is1, std::size_t Offset, std::size_t ... Is2>
    struct concat_seq<index_sequence<Is1...>, Offset, index_sequence<Is2...>>
    {
        using type = index_sequence<Is1..., (Offset + Is2)...>;
    };
}

template <std::size_t N, std::size_t E>
using gen_seq = typename detail::concat_seq<typename make_index_sequence<E>::type, E + 1, typename make_index_sequence<(N > E) ? (N - E - 1) : 0>::type>::type;

static_assert(std::is_same<index_sequence<0, 1, 3, 4>, gen_seq<5, 2>>::value, "");
static_assert(std::is_same<index_sequence<1, 2>, gen_seq<3, 0>>::value, "");
static_assert(std::is_same<index_sequence<0, 1, 2, 3>, gen_seq<4, 4>>::value, "");
Run Code Online (Sandbox Code Playgroud)

实例