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

新手上路,请多包涵

我很喜欢增加可变参数模板并开始摆弄这个新功能。我试图了解 std::index_sequence 的实现细节(用于元组实现)。我在那里看到了示例代码,但我真的想要一步一步地解释 std::index_sequence 是如何编码的,以及每个阶段的元编程主体。想想 真的 傻了:)

原文由 user3613174 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
1 个回答

我在那里看到了示例代码,但我真的想要一步一步地解释如何对 index_sequence 进行编码以及每个阶段的元编程主体。

你问的不是很简单的解释……

嗯… 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> 传递到 std::index_sequence<0, 1, 2, ..., N-1>

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

Non exactly the standard index sequence, that pass from std::integer_sequence , but fixing the std::size_t type you can get a reasonable indexSequence / makeIndexSequence pair使用以下代码。

 // 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> 变成 index_sequenxe<0, 1, 2>

  • 我们有 makeIndexSequence<3> 定义为 typename indexSequenceHelper<3>::type [ N3

  • indexSequenceHelper<3> match only the general case so inherit from indexSequenceHelper<2, 2> [ N is 3 and Next... is empty]

  • indexSequenceHelper<2, 2> match only the general case so inherit from indexSequenceHelper<1, 1, 2> [ N is 2 and Next... is 2 ]

  • indexSequenceHelper<1, 1, 2> match only the general case so inherit from indexSequenceHelper<0, 0, 1, 2> [ N is 1 and Next... is 1, 2 ]

  • indexSequenceHelper<0, 0, 1, 2> match both cases (general an partial specialization) so the partial specialization is applied and define type = indexSequence<0, 1, 2> [ Next... is 0, 1, 2 ]

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

希望这可以帮助。

- - 编辑 - -

一些澄清:

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

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

原文由 max66 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题