問題描述
我很喜歡使用可變參數(shù)模板,并開始擺弄這個新功能.我試圖了解 std::index_sequence
的實現(xiàn)細節(jié)(用于元組實現(xiàn)).我在那里看到了示例代碼,但我真的想要一步一步地解釋 std::index_sequence
是如何編碼的,以及每個階段有問題的元編程原理.想想真的愚蠢的:)
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 :)
推薦答案
我在那里看到了示例代碼,但我真的想要一步一步地解釋 index_sequence 是如何編碼的,以及每個階段的元編程原理.
I see sample code around there, but I really want a dumbed down step by step explanation of how an index_sequence is coded and the meta programming principal in question for each stage.
你問的東西解釋起來并不簡單......
What you ask isn't exactly trivial to explain...
嗯... std::index_sequence
本身很簡單:定義如下
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...>;
實質(zhì)上是一個無符號整數(shù)的模板容器.
that, substantially, is a template container for unsigned integer.
棘手的部分是 std::make_index_sequence
的實現(xiàn).也就是說:棘手的部分是從 std::make_index_sequence
傳遞到 std::index_sequence<0, 1, 2, ..., N-1>
.
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>
.
我建議您一個可能的實現(xiàn)(不是一個很好的實現(xiàn),但簡單(我希望)理解),我將嘗試解釋它是如何工作的.
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.
不完全是從 std::integer_sequence
傳遞過來的標準索引序列,但是修復(fù) std::size_t
類型你可以獲得一個合理的 indexSequence
/makeIndexSequence
與以下代碼配對.
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.
我們可以點對點地看到 makeIndexSequence<3>
如何變成 index_sequenxe<0, 1, 2>
.
We can see, point to point, how makeIndexSequence<3>
become index_sequenxe<0, 1, 2>
.
我們將
makeIndexSequence<3>
定義為typename indexSequenceHelper<3>::type
[N
是>3
]
We have that
makeIndexSequence<3>
is defined astypename indexSequenceHelper<3>::type
[N
is3
]
indexSequenceHelper<3>
僅匹配一般情況,因此繼承自 indexSequenceHelper<2, 2>
[N
是 3
和 Next...
為空]
indexSequenceHelper<3>
match only the general case so inherit from indexSequenceHelper<2, 2>
[N
is 3
and Next...
is empty]
indexSequenceHelper<2, 2>
只匹配一般情況,因此繼承自 indexSequenceHelper<1, 1, 2>
[N
> 是 2
和 Next...
是 2
]
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>
僅匹配一般情況,因此繼承自 indexSequenceHelper<0, 0, 1, 2>
[N
是 1
和 Next...
是 1, 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>
匹配這兩種情況(一般為部分特化),因此應(yīng)用部分特化并定義 type = indexSequence<0, 1, 2>
[Next...
是 0, 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
]
結(jié)論:makeIndexSequence<3>
是indexSequence<0,1,2>
.
希望這會有所幫助.
--- 編輯---
一些說明:
std::index_sequence
和std::make_index_sequence
從 C++14 開始可用
std::index_sequence
andstd::make_index_sequence
are available starting from C++14
我的示例很簡單(我希望)易于理解,但是(正如 aschepler 所指出的)具有很大的限制,即線性實現(xiàn);我的意思是:如果你需要 index_sequence<0, 1, ... 999>
,使用 makeIndexSequence<1000>
你可以遞歸地實現(xiàn) 1000 個不同的 indexSequenceHelper
;但是有一個遞歸限制(編譯器形式編譯器不同)可以小于 1000;還有其他算法可以限制遞歸次數(shù),但解釋起來更復(fù)雜.
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.
這篇關(guān)于std::make_index_sequence 和 std::index_sequence 的細節(jié)的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!