I am using a fold expression to print elements in a variadic pack, but how do I get a space in between each element?
Currently the output is "1 234", the desired output is "1 2 3 4"
template<typename T, typename Comp = std::less<T> >
struct Facility
{
template<T ... list>
struct List
{
static void print()
{
}
};
template<T head,T ... list>
struct List<head,list...>
{
static void print()
{
std::cout<<"\""<<head<<" ";
(std::cout<<...<<list);
}
};
};
template<int ... intlist>
using IntList = typename Facility<int>::List<intlist...>;
int main()
{
using List1 = IntList<1,2,3,4>;
List1::print();
}
you can that
#include <iostream>
template<typename T>
struct Facility
{
template<T head,T ... list>
struct List
{
static void print()
{
std::cout<<"\"" << head;
((std::cout << " " << list), ...);
std::cout<<"\"";
}
};
};
template<int ... intlist>
using IntList = typename Facility<int>::List<intlist...>;
int main()
{
using List1 = IntList<1,2,3,4>;
List1::print();
}
the fold expression ((std::cout << " " << list), ...)
will expands to ((std::cout << " " << list1), (std::cout << " " << list2), (std::cout << " " << list3)...)
If you need space only between numbers (and not after the last or before the first too), you might do:
template <std::size_t... Is>
void print_seq(std::index_sequence<Is...>)
{
const char* sep = "";
(((std::cout << sep << Is), sep = " "), ...);
}
Demo
(It is similar to my "runtime version") for regular containers with for-loop.
In general, you use recursion for tasks like this.
You have to define what happens when there are 2 or more and 1 elements in the list and recursively fall back to those definitions:
template <int ...> struct List;
template <int First, int Second, int ... More> struct List {
static void print() {
std::cout << First << " ";
List<Second, More ...>::print();
}
};
template <int Last> struct List {
static void print() {
std::cout << Last;
}
};
You can reuse print()
to achieve this behaviour. Afterall you are doing a fold
operation which is by definition resursive.
Live Demo
template<T head,T ... rest_of_pack>
struct List<head , rest_of_pack...>
{
static void print_()
{
std::cout<<head<<" ";
List<rest_of_pack...>::print();
}
};
If you want to process many elements this way you might run into problems with template depth (gcc for instance has a limit of 900
). Lucky for you you can use the -ftemplate-depth=
option to tweak this behaviour.
You can compile with -ftemplate-depth=100000
and make it work. Note that compilation time will skyrocket (most likely) or in thhe worst case you run out of memory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With