在 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,
我把排序函数留给你作为简单练习:-)
所以我正在做一些作业,我必须在 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,
我把排序函数留给你作为简单练习:-)