在C ++ 11中打印编译时整数序列

时间:2017-07-24 03:34:59

标签: c++ c++11 sequence variadic-templates variadic

所以我做了一些功课,我必须在C ++ 11中编写自己的编译时整数序列并为它编写一些函数(print,concat,sort等)但是我&# 39;我在处理这些事情的过程中遇到了一些麻烦。

template<typename T, typename Comp = std::less<int>>
struct Facility{

    template<T ... Nums>
    struct List{

        struct Element<T ... nums>{};

        template<unsigned num, T val, T ... rest>
        struct Element{
            unsigned index = num;
            T value = val;
            Element<index-1, rest...> others;
        };

        template<unsigned num, T val, T ... rest>
        struct Element<0, val>{
            unsigned index = 0;
            T value = val;
        };

        static constexpr Element<sizeof...(Nums)-1,Nums...> elem = {};

        static void Print()
        {
            // Prints out the list
        }
    };

};

using IntList = typename Facility<int>::List<intlist...>;

int main()
{
    using List1 = IntList<1, 2, 3>;
    List1::print()
}

我想知道我是否走上了正确的轨道,所以我不能让自己陷入死胡同。我对static print()中的static constexprList成员并非100%肯定,但我无法想到任何其他方法可以使其发挥作用。

2 个答案:

答案 0 :(得分:4)

不要那样不必要地嵌套这样的类型。写一个<T,Ts...>序列。

不要将操作耦合到该类型。在外部编写操作(尾部,头部)。

从C ++ 14中的std::integer_sequence<T,T...>中汲取灵感。

如果您需要在OP中描述该界面,请用平面编写它。

到目前为止,最容易编写的是合并排序。

利用std::integral_constant,即C ++ 11。编写一个带有模板模板参数和一个整数列表的元函数,并将每个积分常量作为类型传递给,并生成一个类型列表template<class...Ts>struct types{};作为输出。请拨打此foreach_int

编写foreach_type,它接受一个类型列表并在每个元素上调用一个函数对象。现在印刷是微不足道的; template<class list> void print_list(){ foreach_type( foreach_int< idenitity, list >{}, print{} ); }其中template<cls T> void print(T && t}{std::cout<<t;}

其中每一个都更容易推理,编写它们可以让你打印每个&#34;。

但也许我有点疯了。

答案 1 :(得分:0)

我不清楚你想要获得什么以及你做了什么的意义(为什么Facility?为什么List在设施内?)。

我只是举例说明如何在没有递归的情况下编写Print(),使用未使用的数组(并定义IntList,如Yakk建议的那样,从std::integer_sequence获得灵感

#include <iostream>
#include <functional>

template <typename T, T ... Nums>
struct IntList
 {
   static void Print (std::ostream & s = std::cout)
    {
      using unused = int[];
      (void)unused { 0, ((void)(s << Nums << ", "), 0)... };
      s << std::endl;
    }
 };

int main()
 {
   using List1 = IntList<int, 1, 2, 3>;
   List1::Print();
 }

如果您可以使用C ++ 17而不是C ++ 11 / C ++ 14,那么您可以在没有未使用的hack的情况下编写Print(),只需解压缩Nums,如下所示

   static void Print (std::ostream & s = std::cout)
    { (s << ... << (s << Nums, ", ")) << std::endl; }

关于concat和sort,我想你想要成员函数返回(例如,concat)一个IntList,其中包含两个数字列表的串联。

一个简单的concat示例可以是IntList

的以下静态成员
template <T ... Nums2>
static constexpr IntList<T, Nums..., Nums2...>
   Concat (IntList<T, Nums2...> const &)
 { return {}; } 

所以你可以写点像

constexpr IntList<int, 1, 2, 3> l1;
constexpr IntList<int, 4, 5, 6> l2;

constexpr auto l3 = l1.Concat(l2);

l3.Print(); // print 1, 2, 3, 4, 5, 6,

我将sort函数作为简单的练习留给你: - )