如何反转整数参数包? [英] How to reverse an integer parameter pack?

查看:60
本文介绍了如何反转整数参数包?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可悲的是,我不能使用的任何问题 /库的问题,因为我正在为嵌入式操作系统,仅具有可用的 使用裸露的C ++,因此没有std::tuplestd::forwardstd::applystd::anything_else.

Sadly, I cannot use any of stl/std libraries from C++, because I am programming for a embedded Operating System which only has available gcc 4.4.4 with bare C++, so, no std::tuple, std::forward, std::apply or std::anything_else.

为帮助您理解生成的元通用代码,我将展示一个使用,因为它可以选择向我们显示生成的/

查看生成的代码:

We can see the generated code using clang:

$ clang++ -Xclang -ast-print -fsyntax-only generator.cpp > expanded.cpp

template <int ...> struct MetaSequenceOfIntegers {
};
template<> struct MetaSequenceOfIntegers<<5, 1, 0>> {
};
template <int AccumulatedSize, typename Tn, int ...GeneratedSequence> struct GeneratorOfIntegerSequence
template<> struct GeneratorOfIntegerSequence<0, int (char, int, char), <>> {
    typedef typename GeneratorOfIntegerSequence<0 + sizeof(char), int (int, char), 0>::type type;
}
template<> struct GeneratorOfIntegerSequence<1, int (int, char), <0>> {
    typedef typename GeneratorOfIntegerSequence<1 + sizeof(int), int (char), 1, 0>::type type;
}
template<> struct GeneratorOfIntegerSequence<5, int (char), <1, 0>> {
    typedef typename GeneratorOfIntegerSequence<5 + sizeof(char), int (), 5, 1, 0>::type type;
}
template<> struct GeneratorOfIntegerSequence<6, int (), <5, 1, 0>> {
    typedef MetaSequenceOfIntegers<5, 1, 0> type;
};
template <int AccumulatedSize, typename Grouper, typename Head, typename ...Tail, int ...GeneratedSequence> struct GeneratorOfIntegerSequence<AccumulatedSize, type-parameter-0-1 (type-parameter-0-2, type-parameter-0-3...), <GeneratedSequence...>> {
    typedef typename GeneratorOfIntegerSequence<AccumulatedSize + sizeof(Head), Grouper (Tail...), AccumulatedSize, GeneratedSequence...>::type type;
};
template <int AccumulatedSize, typename Grouper, int ...GeneratedSequence> struct GeneratorOfIntegerSequence<AccumulatedSize, type-parameter-0-1 (), <GeneratedSequence...>> {
    typedef MetaSequenceOfIntegers<GeneratedSequence...> type;
};
template <int ...Sequence> void intergers_sequencer_generator(MetaSequenceOfIntegers<Sequence...>) {
    int array[] = {Sequence...};
}
template<> void intergers_sequencer_generator<<5, 1, 0>>(MetaSequenceOfIntegers<5, 1, 0>) {
    int array[] = {5, 1, 0};
}
int main(int argc, const char *argv[]) {
    intergers_sequencer_generator(GeneratorOfIntegerSequence<0, int (char, int, char)>::type());
    return 0;
}

生成元编程列表的顺序是我需要的相反顺序.代替int array[] = {5, 1, 0},它应该是int array[] = {0, 1, 5}.

The meta programming list is generated is on reversed order I need it to be. Instead of int array[] = {5, 1, 0}, it should be int array[] = {0, 1, 5}.

我只是在示例代码中更改了这一行,才设法以正确的顺序生成了列表:

I managed to generated the list on the correct order just changing this line on in example code:

< AccumulatedSize + sizeof(Head), Grouper( Tail... ), GeneratedSequence..., AccumulatedSize
// to -->
< AccumulatedSize + sizeof(Head), Grouper( Tail... ), AccumulatedSize, GeneratedSequence...

但是让我们假设我不能这样做,因为该列表是从我没有控制权的第三部分输入的.如何在不使用任何标准库函数的情况下将参数包<5, 1, 0>反向转换为<0, 1, 5>?

But let us supposed I could not do that because the list is input from a third part which I do not have control. How can I reverse the parameter pack <5, 1, 0> to <0, 1, 5> without using any std library functions?

在我的第一次尝试中,我尝试使用与生成整数列表相同的策略,但是无法对其进行编译:

In my first attempt, I tried to use the same strategy as the one I did to generate the integer list, but I could not make it to compile:

template<int ...>
struct MetaSequenceOfIntegers { };

template<int AccumulatedSize, typename Tn, int... GeneratedSequence>
struct GeneratorOfIntegerSequence;

template<int AccumulatedSize, typename Grouper, typename Head, typename... Tail, int... GeneratedSequence>
struct GeneratorOfIntegerSequence< AccumulatedSize, Grouper( Head, Tail... ), GeneratedSequence... >
{
    typedef typename GeneratorOfIntegerSequence
            < AccumulatedSize + sizeof(Head), Grouper( Tail... ), AccumulatedSize, GeneratedSequence...
            >::type type;
};

template<int AccumulatedSize, typename Grouper, int... GeneratedSequence>
struct GeneratorOfIntegerSequence<AccumulatedSize, Grouper(), GeneratedSequence...>
{
  typedef MetaSequenceOfIntegers<GeneratedSequence...> type;
};

// The new code starts here
template<int ...>
struct MetaSequenceReversed { };

template<typename Tn, int... GeneratedSequence>
struct ReversorOfIntegerSequence;

template<typename Grouper, int Head, int... Tail, int... GeneratedSequence>
struct ReversorOfIntegerSequence< Grouper( Head, Tail... ), GeneratedSequence... >
{
    typedef typename ReversorOfIntegerSequence
            < Grouper( Tail... ), GeneratedSequence...
            >::type type;
};

template<typename Grouper, int... GeneratedSequence>
struct ReversorOfIntegerSequence<Grouper(), GeneratedSequence...>
{
  typedef MetaSequenceReversed<GeneratedSequence...> type;
};

template<int ...ReversedSequence>
void intergers_sequencer_reversor(MetaSequenceReversed<ReversedSequence...>) {
    int reversed_array[] = {ReversedSequence...};
}

template<int ...Sequence>
void intergers_sequencer_generator(MetaSequenceOfIntegers<Sequence...>) {
    int array[] = {Sequence...};
    intergers_sequencer_reversor( ReversorOfIntegerSequence< int(Sequence...) >::type() );
}

int main(int argc, char const *argv[])
{
    intergers_sequencer_generator( GeneratorOfIntegerSequence< 0, int(char, int, char) >::type() );
    return 0;
}

当我尝试构建它时,出现此错误:

When I try to build this, I got this error:

generator.cpp:29:35: error: template argument for template type parameter must be a type
struct ReversorOfIntegerSequence< Grouper( Head, Tail... ), GeneratedSequence... >
                                  ^~~~~~~~~~~~~~~~~~~~~~~~
generator.cpp:25:19: note: template parameter is declared here
template<typename Tn, int... GeneratedSequence>
                  ^
generator.cpp:50:62: error: template argument for template type parameter must be a type
    intergers_sequencer_reversor( ReversorOfIntegerSequence< int(Sequence...) >::type() );
                                                             ^~~~~~~~~~~~~~~~
generator.cpp:25:19: note: template parameter is declared here
template<typename Tn, int... GeneratedSequence>
                  ^


参考文献:


References:

  1. 可变参数模板,参数包及其在参数列表中讨论的模糊性
  2. 一个元组以调用匹配的函数指针
  3. 可以用C ++看到模板实例化的代码吗?编译器
  4. 使用可变参数模板构建函数参数
  5. 如何反转顺序可变参数模板函数的参数集?
  1. Variadic templates, parameter pack and its discussed ambiguity in a parameter list
  2. "unpacking" a tuple to call a matching function pointer
  3. Can we see the template instantiated code by C++ compiler
  4. Build function parameters with variadic templates
  5. How to reverse the order of arguments of a variadic template function?

推荐答案

如何在不使用任何标准库函数的情况下将参数pack <5, 1, 0>转换为<0, 1, 5>?

不确定要确切地使用什么功能,但是...对我来说似乎很容易.

Not sure to understand what do you exactly can use but... it seems easy to me.

给出如下的帮助结构

template <typename, typename>
struct RS_helper;

template <int ... As, int B0, int ... Bs>
struct RS_helper<MetaSequenceOfIntegers<As...>,
                 MetaSequenceOfIntegers<B0, Bs...>>
   : RS_helper<MetaSequenceOfIntegers<B0, As...>,
               MetaSequenceOfIntegers<Bs...>>
 { };

template <typename T>
struct RS_helper<T, MetaSequenceOfIntegers<>>
 { using type = T; };

还原结构可以很简单

template <int ... Is>
struct RevertSequence
   : RS_helper<MetaSequenceOfIntegers<>, MetaSequenceOfIntegers<Is...>>
 { };

我想反向函数可能有用

template <int ... Is>
constexpr typename RevertSequence<Is...>::type
   revertSequenceFunction (MetaSequenceOfIntegers<Is...> const &)
 { return {}; }

我建议对原始代码进行修改,并增加反向序列(也使用std::cout打印序列,但显然可以将其删除).

I propose a modified version of your original code with addition of reversed sequence (using also std::cout to print the sequences, but you can remove it, obviously).

#include <iostream>

template <int ...>
struct MetaSequenceOfIntegers
 { };

template <int AccumulatedSize, typename Tn, int ... GeneratedSequence>
struct GeneratorOfIntegerSequence;

template <int AccumulatedSize, typename Grouper, typename Head,
          typename ... Tail, int ... GeneratedSequence>
struct GeneratorOfIntegerSequence<AccumulatedSize, Grouper(Head, Tail...),
                                  GeneratedSequence... >
 { typedef typename GeneratorOfIntegerSequence
            <AccumulatedSize+sizeof(Head), Grouper(Tail...),
             AccumulatedSize, GeneratedSequence...>::type type; };

template <int AccumulatedSize, typename Grouper, int ... GeneratedSequence>
struct GeneratorOfIntegerSequence<AccumulatedSize, Grouper(),
                                  GeneratedSequence...>
 { typedef MetaSequenceOfIntegers<GeneratedSequence...> type; };

template <int ... Sequence>
void intergers_sequencer_generator(MetaSequenceOfIntegers<Sequence...>)
 {
   using unused = int[];

   (void)unused { 0, (std::cout << Sequence << ' ', 0)... };

   std::cout << std::endl;
 }


template <typename, typename>
struct RS_helper;

template <int ... As, int B0, int ... Bs>
struct RS_helper<MetaSequenceOfIntegers<As...>,
                 MetaSequenceOfIntegers<B0, Bs...>>
   : RS_helper<MetaSequenceOfIntegers<B0, As...>,
               MetaSequenceOfIntegers<Bs...>>
 { };

template <typename T>
struct RS_helper<T, MetaSequenceOfIntegers<>>
 { using type = T; };

template <int ... Is>
struct RevertSequence
   : RS_helper<MetaSequenceOfIntegers<>, MetaSequenceOfIntegers<Is...>>
 { };

template <int ... Is>
constexpr typename RevertSequence<Is...>::type
   revertSequenceFunction (MetaSequenceOfIntegers<Is...> const &)
 { return {}; }

int main ()
 {
   intergers_sequencer_generator(
      GeneratorOfIntegerSequence<0, int(char, int, char)>::type());

   intergers_sequencer_generator(
      revertSequenceFunction(
         GeneratorOfIntegerSequence<0, int(char, int, char)>::type()));
 }

这篇关于如何反转整数参数包?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆