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

Printing compile-time integer sequence in C++11

本文关键字:整数 编译 C++11 打印      更新时间:2023-10-16

所以我正在做一些功课,我必须在 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()
}

我只是想知道我是否走在正确的轨道上,这样我就不会把自己弄成死胡同。我对static print()Liststatic constexpr成员不是 100% 确定,尽管我想不出任何其他方法可以使其工作。

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

不要将操作耦合到类型。 在外部写入操作(尾部、头部(。

从 C++14std::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;}

这些中的每一个都更容易推理,并且撰写它们可以让您"打印每个"。

但也许我有点疯了。

我不清楚你到底想得到什么以及你所做的是什么意思(为什么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,

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