实现C++模板来生成给定范围的索引序列

问题描述 投票:0回答:2

因此,C++14 提供了 struct

make_index_sequence<N>
来生成从
0
N-1
的索引序列。我想知道如何实现一个来生成给定范围内的索引序列。例如:

template <size_t Min, size_t Max>
struct make_index_range;  

// make_index_range<5, 9> will give index_sequence<5, 6, 7, 8>
c++ templates metaprogramming c++14
2个回答
12
投票

您定义

index_range
的方式(在编辑问题之前)答案很简单:

template<std::size_t Min, std::size_t Max>
  using make_index_range = index_range<Min, Max>;

这不是很有用。

所以我假设你的意思是

make_index_range<5, 9>
会给出
index_sequence<5, 6, 7, 8>
,可以这样做:

#include <utility>

template<std::size_t N, std::size_t... Seq>
  constexpr std::index_sequence<N + Seq ...>
  add(std::index_sequence<Seq...>)
  { return {}; }

template<std::size_t Min, std::size_t Max>
  using make_index_range = decltype(add<Min>(make_index_sequence<Max-Min>()));

或者,如果您希望

make_index_range
成为类模板,请按上述方式定义
add
,然后:

template<std::size_t Min, std::size_t Max>
  struct make_index_range {
    using type = decltype(add<Min>(make_index_sequence<Max-Min>()));
  };

(但是这样你就必须使用

make_index_range<5, 9>::type
,所以别名模板可能更好,并且更接近
make_index_sequence
的工作方式。)


0
投票

我知道这个问题是用 c++14 标记的,但为标准的较新版本提供一个版本可能会很有趣,其中元编程更容易一些(尽管在本示例中并不那么明显)。

此外,我还需要有一个不一定大于 0 的整数范围,因此以下代码(适用于 c++20):

#include <numeric>
#include <array>

template<typename T, T Min, T Max>
constexpr auto make_integer_range ()
{
    static_assert (Max>=Min);

    // we create an array filled with the integers from the given [Min,Max] bounds.
    constexpr auto arr = []
    {
        std::array<T, Max-Min+1> a;
        std::iota (a.begin(), a.end(), Min);
        return a;
    } ();

    // we create the integer sequence from the content of the array
    auto build = [&arr] <std::size_t... Is> (std::index_sequence<Is...>)
    {
        return std::integer_sequence<T, arr[Is]...>{};
    };

    return build (std::make_index_sequence<arr.size()>{});
}

// integer sequence of -1,0,1,2,3
constexpr auto myrange = make_integer_range<int,-1,3> (); 

int main()  {}
© www.soinside.com 2019 - 2024. All rights reserved.