std::make_index_sequence 和 std::index_sequence 的详细信息

2024-04-14

我很喜欢增加可变参数模板,并开始摆弄这个新功能。我正在尝试了解实施细节std::index_sequence's(用于元组实现)。我在那里看到了示例代码,但我真的想要一个简单的逐步解释,说明如何std::index_sequence已编码,并且每个阶段的元编程原理都有问题。思考really简单化 :)


我在那里看到了示例代码,但我真的想要一个简单的逐步解释,说明如何对 index_sequence 进行编码以及每个阶段的元编程原理。

你问的问题并不完全是微不足道的解释......

Well... std::index_sequence本身很简单:定义如下

template<std::size_t... Ints>
using index_sequence = std::integer_sequence<std::size_t, Ints...>;

本质上,它是无符号整数的模板容器。

棘手的部分是实施std::make_index_sequence。那就是:棘手的部分是从std::make_index_sequence<N> to std::index_sequence<0, 1, 2, ..., N-1>.

我向您建议一个可能的实现(不是一个很好的实现,但(我希望)很容易理解),我将尝试解释它是如何工作的。

不完全是标准索引序列,来自std::integer_sequence,但修复std::size_t类型你可以得到一个合理的indexSequence/makeIndexSequence与以下代码配对。

// index sequence only
template <std::size_t ...>
struct indexSequence
 { };

template <std::size_t N, std::size_t ... Next>
struct indexSequenceHelper : public indexSequenceHelper<N-1U, N-1U, Next...>
 { };

template <std::size_t ... Next>
struct indexSequenceHelper<0U, Next ... >
 { using type = indexSequence<Next ... >; };

template <std::size_t N>
using makeIndexSequence = typename indexSequenceHelper<N>::type;

我认为理解它如何工作的一个好方法是遵循一个实际的例子。

我们可以看到,点对点,如何makeIndexSequence<3> become index_sequenxe<0, 1, 2>.

  • 我们有那个makeIndexSequence<3>定义为typename indexSequenceHelper<3>::type [N is 3]

  • indexSequenceHelper<3>仅匹配一般情况,因此继承自indexSequenceHelper<2, 2> [N is 3 and Next...是空的]

  • indexSequenceHelper<2, 2>仅匹配一般情况,因此继承自indexSequenceHelper<1, 1, 2> [N is 2 and Next... is 2]

  • indexSequenceHelper<1, 1, 2>仅匹配一般情况,因此继承自indexSequenceHelper<0, 0, 1, 2> [N is 1 and Next... is 1, 2]

  • indexSequenceHelper<0, 0, 1, 2>匹配两种情况(一般是部分特化),因此应用部分特化并定义type = indexSequence<0, 1, 2> [Next... is 0, 1, 2]

结论:makeIndexSequence<3> is indexSequence<0, 1, 2>.

希望这可以帮助。

- - 编辑 - -

一些澄清:

  • std::index_sequence and std::make_index_sequence从 C++14 开始可用

  • 我的例子很简单(我希望)易于理解,但是(正如 aschepler 所指出的)线性实现有很大的限制;我的意思是:如果你需要index_sequence<0, 1, ... 999>, using makeIndexSequence<1000>你以递归的方式实现了 1000 个不同的indexSequenceHelper;但有一个递归限制(编译器形式编译器不同),可以小于1000;还有其他限制递归次数的算法,但解释起来更复杂。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

std::make_index_sequence 和 std::index_sequence 的详细信息 的相关文章

随机推荐