所以我做了一些功课,我必须在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 constexpr
和List
成员并非100%肯定,但我无法想到任何其他方法可以使其发挥作用。
答案 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函数作为简单的练习留给你: - )