use*_*174 15 c++ templates template-meta-programming variadic-templates c++14
我很喜欢增加可变参数模板,并开始摆弄这个新功能.我试图了解std::index_sequences 的实现细节(用于元组实现).我看到那里的示例代码,但我真的想要逐步解释如何std::index_sequence编码和每个阶段的元编程主题.想真的傻了:)
max*_*x66 21
我看到那里的示例代码,但我真的想要逐步解释index_sequence如何编码以及每个阶段的元编程主题.
你问的问题并不是很容易解释......
嗯... std::index_sequence本身很简单:定义如下
template<std::size_t... Ints>
using index_sequence = std::integer_sequence<std::size_t, Ints...>;
Run Code Online (Sandbox Code Playgroud)
实质上,它是无符号整数的模板容器.
棘手的部分是实施std::make_index_sequence.那就是:棘手的部分是从传递std::make_index_sequence<N>到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;
Run Code Online (Sandbox Code Playgroud)
我认为理解其工作原理的一个好方法是遵循一个实际的例子.
我们可以看到,点到点,如何makeIndexSequence<3>成为index_sequenxe<0, 1, 2>.
我们将其makeIndexSequence<3>定义为typename indexSequenceHelper<3>::type[ N是3]
indexSequenceHelper<3>只匹配一般情况,所以从indexSequenceHelper<2, 2>[ Nis 3and Next...is empty] 继承
indexSequenceHelper<2, 2>只匹配一般情况所以继承自indexSequenceHelper<1, 1, 2>[ N是2和Next...是2]
indexSequenceHelper<1, 1, 2>只匹配一般情况所以继承自indexSequenceHelper<0, 0, 1, 2>[ N是1和Next...是1, 2]
indexSequenceHelper<0, 0, 1, 2>匹配两种情况(一般是部分特化)所以应用部分特化并定义type = indexSequence<0, 1, 2>[ Next...是0, 1, 2]
结论:makeIndexSequence<3>是indexSequence<0, 1, 2>.
希望这可以帮助.
---编辑---
一些澄清:
std::index_sequence和std::make_index_sequence可购自开始C++ 14
我的例子很简单(我希望)理解但是(正如aschepler所指出的那样)有一个很大的限制,即线性实现; 我的意思是:如果你需要index_sequence<0, 1, ... 999>,使用makeIndexSequence<1000>你实现,以递归的方式,1000不同indexSequenceHelper; 但是有一个递归限制(编译器形式编译器不同),可以小于1000; 还有其他算法可以限制递归次数,但解释起来却更复杂.
pap*_*aga 10
为了完整起见,我将添加更现代的实现std::make_index_sequence,使用if constexpr和auto,使模板编程更像“常规”编程。
template <std::size_t... Ns>
struct index_sequence {};
template <std::size_t N, std::size_t... Is>
auto make_index_sequence_impl() {
// only one branch is considered. The other may be ill-formed
if constexpr (N == 0) return index_sequence<Is...>(); // end case
else return make_index_sequence_impl<N-1, N-1, Is...>(); // recursion
}
template <std::size_t N>
using make_index_sequence = std::decay_t<decltype(make_index_sequence_impl<N>())>;
Run Code Online (Sandbox Code Playgroud)
我强烈建议使用这种样式的模板编程,这很容易推理。
| 归档时间: |
|
| 查看次数: |
8214 次 |
| 最近记录: |