(C++11) 可变参数模板序列打印
Posted
技术标签:
【中文标题】(C++11) 可变参数模板序列打印【英文标题】:(C++11) Variadic template sequence printing 【发布时间】:2020-11-18 18:59:37 【问题描述】:我遇到了一个模板元编程挑战,即仅使用 C++11 标准打印出一系列 2 的幂的整数,我已经成功完成了:
#include <iostream>
template <size_t... Ns>
struct index_sequence
static void print()
const size_t numbers[] = Ns...;
for (const auto& number : numbers)
std::cout << number << ", ";
std::cout << std::endl;
;
//#include <cmath>
template <size_t Counter, size_t... Rest>
struct make_sequence_impl
using type = typename make_sequence_impl<
Counter - 1,
static_cast<size_t>(1) << Counter, Rest...>::type;
;
template <size_t... Rest>
struct make_sequence_impl<0, Rest...>
using type = index_sequence<static_cast<size_t>(1) << 0, Rest...>;
;
template <size_t T>
using make_sequence = typename make_sequence_impl<T>::type;
int main()
make_sequence<N>::print();
假设 N 为 5,它将打印 1、2、4、8、16。
然而,我随后被要求做同样的事情,只是这次我必须以相反的顺序打印它们(即 N = 5 时,16、8、4、2、1)。我完全被难住了,但我很确定它只涉及对代码的轻微更改,我不知道如何。
任何帮助将不胜感激。几天前开始接触模板元编程。
【问题讨论】:
在循环中使用reverse_iterator
?
我会模仿std::make_integer_sequence
拥有sequence<Is...>
,然后使用转换方法拥有sequence<(1 << Is)...>
或sequence<(1 << (sizeof...(Is) - 1 -Is))...>
。
【参考方案1】:
不确定这是否是最小的变化,但您可能 "push_front" 而不是序列,而是 "push_back"。
template <size_t Counter, size_t... Rest>
struct make_sequence_impl
using type = typename make_sequence_impl<
Counter - 1,
Rest...,
static_cast<size_t>(1) << Counter>::type;
;
template <size_t... Rest>
struct make_sequence_impl<0, Rest...>
using type = index_sequence<Rest..., static_cast<size_t>(1) << 0>;
;
Demo
在我这边,我会模仿std::make_index_sequence
拥有0, 1, 2, .., N-1
,然后直接使用它:
emplate <size_t Counter, size_t... Rest>
struct make_sequence_impl
using type = typename make_sequence_impl<
Counter - 1,
Counter,
Rest...>::type;
;
template <size_t... Rest>
struct make_sequence_impl<0, Rest...>
using type = index_sequence<0, Rest...>;
;
然后
template <std::size_t ... Is>
void print( index_sequence<Is...> )
for (const auto& number : Is...)
std::cout << number << ", ";
std::cout << std::endl;
template <std::size_t ... Is>
void print_pow2( index_sequence<Is...> )
print(index_sequence<(1u << Is)...>);
template <std::size_t ... Is>
void print_pow2_inv( index_sequence<Is...> )
print(index_sequence<(1u << (sizeof...(Is) - 1 - Is))...>);
Demo
【讨论】:
天哪……我怎么没想到呢?我一直认为你不能“push_front”一个模板化的参数包序列,而我正接近探索实现一个反向解包的函数的地步。非常感谢!我希望我能在这方面做得更好...... 关于“push_front”实现和“minic make_index_sequence”实现的另一个问题。我都试过了,他们都表现得像预期的那样。两者之间是否存在任何实际差异,或者后者只是您会做的一种实现? 可能首先是命名问题,因为您的make_sequence
与std::make_sequence
不匹配,make_sequnce_pow
本来会更好的命名。然后一旦完成一个序列,就更容易操作它,每次我们需要它时重新创建另一个。以上是关于(C++11) 可变参数模板序列打印的主要内容,如果未能解决你的问题,请参考以下文章