使用折叠表达式打印每个元素之间的空格
Print spaces between each element using a fold expression
我正在使用折叠表达式打印可变参数包中的元素,但如何在每个元素之间获得 space?
当前输出为“1 234”,所需输出为“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();
}
一般来说,您会使用递归来完成这样的任务。
您必须定义当列表中有 2 个或更多元素和 1 个元素时会发生什么,并递归回退到这些定义:
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;
}
};
你可以
#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();
}
折叠表达式 ((std::cout << " " << list), ...)
将扩展为 ((std::cout << " " << list1), (std::cout << " " << list2), (std::cout << " " << list3)...)
您可以重复使用 print()
来实现此行为。毕竟你正在做一个 fold
操作,根据定义它是递归的。
template<T head,T ... rest_of_pack>
struct List<head , rest_of_pack...>
{
static void print_()
{
std::cout<<head<<" ";
List<rest_of_pack...>::print();
}
};
如果您想以这种方式处理许多元素,您可能 运行 会遇到模板深度问题(例如 gcc 的限制为 900
)。幸运的是,您可以使用 -ftemplate-depth=
选项来调整此行为。
您可以使用 -ftemplate-depth=100000
进行编译并使其工作。请注意,编译时间会猛增(很可能),或者在最坏的情况下 运行 内存不足。
如果您只在数字之间需要 space(而不是在最后一个之后或第一个之前),您可以这样做:
template <std::size_t... Is>
void print_seq(std::index_sequence<Is...>)
{
const char* sep = "";
(((std::cout << sep << Is), sep = " "), ...);
}
(这类似于我的 "runtime version")用于带有 for-loop 的常规容器。
我正在使用折叠表达式打印可变参数包中的元素,但如何在每个元素之间获得 space?
当前输出为“1 234”,所需输出为“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();
}
一般来说,您会使用递归来完成这样的任务。
您必须定义当列表中有 2 个或更多元素和 1 个元素时会发生什么,并递归回退到这些定义:
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;
}
};
你可以
#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();
}
折叠表达式 ((std::cout << " " << list), ...)
将扩展为 ((std::cout << " " << list1), (std::cout << " " << list2), (std::cout << " " << list3)...)
您可以重复使用 print()
来实现此行为。毕竟你正在做一个 fold
操作,根据定义它是递归的。
template<T head,T ... rest_of_pack>
struct List<head , rest_of_pack...>
{
static void print_()
{
std::cout<<head<<" ";
List<rest_of_pack...>::print();
}
};
如果您想以这种方式处理许多元素,您可能 运行 会遇到模板深度问题(例如 gcc 的限制为 900
)。幸运的是,您可以使用 -ftemplate-depth=
选项来调整此行为。
您可以使用 -ftemplate-depth=100000
进行编译并使其工作。请注意,编译时间会猛增(很可能),或者在最坏的情况下 运行 内存不足。
如果您只在数字之间需要 space(而不是在最后一个之后或第一个之前),您可以这样做:
template <std::size_t... Is>
void print_seq(std::index_sequence<Is...>)
{
const char* sep = "";
(((std::cout << sep << Is), sep = " "), ...);
}
(这类似于我的 "runtime version")用于带有 for-loop 的常规容器。