问题描述
我喜欢使用可变参数模板,并开始摆弄这个新功能。我正在设法弄清 c继承[ c继承[ N 是 1 和下一步... 是 1、2 ]
indexSequenceHelper< 0,0,1,2> 匹配两种情况(通常是部分专业化),因此应用了部分专业化,并且define type = indexSequence< 0,1,2> [ Next ... 是 0 ,1、2 ]
结论: makeIndexSequence< 3> ; 是 indexSequence< 0,1,2> 。
希望这会有所帮助。
---编辑---
一些说明:
-
std ::从C ++ 14起可用index_sequence 和 std :: make_index_sequence
- <我的例子很简单(我希望)易于理解,但是(正如aschepler指出的那样)有一个很大的限制,那就是线性实现。我的意思是:如果您需要 index_sequence< 0,1,... 999> ,请使用 makeIndexSequence< 1000> 以递归方式实现1000个不同的 indexSequenceHelper ;但是递归限制(编译器表单编译器有所不同)可以小于1000;还有其他限制递归次数的算法,但解释起来比较复杂。
I'm enjoying ramping up on variadic templates and have started fiddling about with this new feature. I'm trying to get my head around the implementation details of std::index_sequence's (used for tuple implementation). I see sample code around there, but I really want a dumbed down step by step explanation of how an std::index_sequence is coded and the meta programming principal in question for each stage. Think really dumbed down :)
What you ask isn't exactly trivial to explain...
Well... std::index_sequence itself is very simple: is defined as follows
template<std::size_t... Ints> using index_sequence = std::integer_sequence<std::size_t, Ints...>;
that, substantially, is a template container for unsigned integer.
The tricky part is the implementation of std::make_index_sequence. That is: the tricky part is pass from std::make_index_sequence<N> to std::index_sequence<0, 1, 2, ..., N-1>.
I propose you a possible implementation (not a great implementation but simple (I hope) to understand) and I'll try to explain how it works.
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 with the following code.
// 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;
I suppose that a good way to understand how it works is follows a practical example.
We can see, point to point, how makeIndexSequence<3> become index_sequenxe<0, 1, 2>.
We have that makeIndexSequence<3> is defined as typename indexSequenceHelper<3>::type [N is 3]
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]
Conclusion: makeIndexSequence<3> is indexSequence<0, 1, 2>.
Hope this helps.
--- EDIT ---
Some clarifications:
std::index_sequence and std::make_index_sequence are available starting from C++14
my example is simple (I hope) to understand but (as pointed by aschepler) has the great limit that is a linear implementation; I mean: if you need index_sequence<0, 1, ... 999>, using makeIndexSequence<1000> you implement, in a recursive way, 1000 different indexSequenceHelper; but there is a recursion limit (compiler form compiler different) that can be less than 1000; there are other algorithms that limits the number of recursions but are more complicated to explain.
这篇关于std :: make_index_sequence和std :: index_sequence的详细信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!