So I'm doing a bit of homework where I have to write my own compile-time integer sequence in C++11 and write a few functions for it (print, concat, sort etc.) but I'm having a bit of trouble wrapping my head around how I would go about writing these things.
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()
}
I'd just like to know if I'm on the right track so I don't work myself into a dead end. I'm not 100% sure on the static print()
and the static constexpr
member in List
, though I can't think of any other way to make it work.
Isn't clear to me what exactly do you want obtain and the meaning of what you have done (why Facility
? why List
inside facility?).
I just give you an example of how to write Print()
without recursion, using an unused array (and defining IntList
, as suggested by Yakk, taking inspiration from 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();
}
If you can use C++17 instead of C++11/C++14, you can write Print()
without the unused hack, simply unpacking Nums
as follows
static void Print (std::ostream & s = std::cout)
{ (s << ... << (s << Nums, ", ")) << std::endl; }
Regarding concat and sort, I suppose you want member function that return (by example, the concat) a IntList
with a concatenation of the two lists of numbers.
The a simple concat example can be the following static member for IntList
template <T ... Nums2>
static constexpr IntList<T, Nums..., Nums2...>
Concat (IntList<T, Nums2...> const &)
{ return {}; }
So you can write something like
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,
I leave you the sort function as simple exercise :-)