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

Printing compile-time integer sequence in C++11

所以我正在做一些作业,我必须在 C++11 中编写自己的编译时整数序列并为其编写一些函数(打印、连接、排序等),但我'我在思考如何着手编写这些东西时遇到了一些麻烦。

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()
}

我只是想知道我是否在正确的轨道上,这样我就不会把自己逼入死胡同。我不是 100% 确定 static print()List 中的 static constexpr 成员,尽管我想不出任何其他方法来让它工作。

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

不要将操作耦合到类型。外部写入操作(tail,head)。

从 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;}

这些中的每一个都更容易推理,将它们组合起来会让你 "print each"。

但也许我有点疯狂。

我不清楚你到底想获得什么以及你所做的事情的意义(为什么 Facility?为什么 List 在设施内?)。

我只是给你一个例子,说明如何在没有递归的情况下使用未使用的数组来编写 Print()(并根据 Yakk 的建议定义 IntList,从 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,你可以编写Print()而不用未使用的hack,只需解包Nums如下

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

关于 concat 和排序,我想你想要的成员函数是 return(例如,concat)一个 IntList 与两个数字列表的串联。

一个简单的连接示例可以是 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,

我把排序函数留给你作为简单练习:-)