【问题标题】:Reversing the order of template (integer) parameters逆转模板(整数)参数的顺序
【发布时间】:2018-10-23 04:22:52
【问题描述】:

我正在尝试根据在a previous thread 中找到的答案反转模板变量std::size_t 参数序列的顺序。但由于某种原因,它不起作用。

这是一个常规的可变参数打印函数:

template<typename = void>
void print(void)
{
    std::cout << std::endl;
}

template<typename... T>
void print(std::size_t index, T... indexes)
{
    std::cout << index << ' ';
    print(indexes...);
}

这是模板类链:

template<std::size_t... Indexes>
class NonRecursiveClass
{
    public:

        void show(void)
        {
            print(Indexes...);
        }
};

template<std::size_t Count, std::size_t Index, std::size_t... Indexes>
class RecursiveClass;

template<std::size_t Count, std::size_t Index, std::size_t... Indexes>
class RecursiveClass : public RecursiveClass<Count - 1u, Indexes..., Index>
{
};

template<std::size_t Index, std::size_t... Indexes>
class RecursiveClass<0u, Index, Indexes...> : public NonRecursiveClass<Index, Indexes...>
{
};

基本上,这个想法是,例如,如果您创建一个 RecursiveClass&lt;5u, 10u, 1u, 6u, 478u, 23u&gt; 对象,它将继承自 NonRecursiveClass&lt;23u, 478u, 6u, 1u, 10u&gt; 对象,并且您的 std::size_t 参数序列在编译时向后。

不幸的是,当我尝试时,我仍然得到原始订单。这是我的主要功能:

int main(void)
{
    RecursiveClass<5u, 10u, 1u, 6u, 478u, 23u> foo;
    foo.show();
    return 0;
}

这是输出:

10 1 6 478 23

我做错了什么?

【问题讨论】:

    标签: c++ variadic-templates c++17 template-meta-programming


    【解决方案1】:

    我做错了什么?

    想想你在这里做什么:

    template<std::size_t Count, std::size_t Index, std::size_t... Indexes>
    class RecursiveClass : public RecursiveClass<Count - 1u, Indexes..., Index>
    

    如果你还没有完成(也就是说,如果Count != 0),那么你要做的就是把第一个移到后面。让我们来看看这个算法:

    RecursiveClass<5, 10, 1, 6, 478, 23>
    └─ RecursiveClass<4, 1, 6, 478, 23, 10> // 10 to the back
       └─ RecursiveClass<3, 6, 478, 23, 10, 1> // 1 to the back
          └─ RecursiveClass<2, 478, 23, 10, 1, 6> // 6 to the back
             ...
    

    我们没有颠倒顺序。我们只是将它旋转一整圈。这就是我们最终打印相同内容的原因。

    你需要做的是pre-将每个元素附加到一个不同的序列:

    template <std::size_t...> struct sequence;
    
    template <typename T, typename U>
    class RecursiveClassImpl;
    
    template <std::size_t I, std::size_t... Is, std::size_t... Js>
    class RecursiveClassImpl<sequence<I, Is...>, sequence<Js...>>
        : public RecursiveClassImpl<sequence<Is...>, sequence<I, Js...>>
    //                                               ^^^^^^^^^^^^^^^^^^
    //                                               NB: prepend
    { };
    
    template <std::size_t... Js>
    class RecursiveClassImpl<sequence<>, sequence<Js...>>
        : public NonRecursiveClass<Js...>
    { };
    
    template<std::size_t... Indexes>
    class RecursiveClass : public RecursiveClassImpl<sequence<Indexes...>, sequence<>>
    { };
    

    【讨论】:

    • 非常感谢先生。我不知道我在想什么,真的。请问您为什么选择将sequence 设为struct 而不是class?我看到的大多数例子似乎更喜欢struct,我想知道为什么会这样:)
    • @Pippin 没关系,它甚至不是一个完整的类型。元编程往往更喜欢struct,因为没有任何要封装的东西,这样您就不必在任何地方输入public
    猜你喜欢
    • 2013-04-01
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 2012-02-05
    • 1970-01-01
    • 2012-05-13
    • 1970-01-01
    相关资源
    最近更新 更多