6

我正在使用折叠表达式来打印可变参数包中的元素,但是如何在每个元素之间获得一个空格?

当前输出为“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();
}
4

4 回答 4

8

你可以

#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)...)

于 2018-07-11T09:42:07.597 回答
8

如果您只需要数字之间的空格(而不是在最后一个之后或第一个之前),您可以这样做:

template <std::size_t... Is>
void print_seq(std::index_sequence<Is...>)
{
    const char* sep = "";
    (((std::cout << sep << Is), sep = " "), ...);
}

演示

(类似于我的“运行时版本”)用于带有 for 循环的常规容器。

于 2019-04-10T08:48:33.410 回答
7

通常,您对此类任务使用递归。

您必须定义当列表中有 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;
    }
};
于 2018-07-11T09:36:43.433 回答
1

您可以重用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并使其工作。请注意,编译时间会飙升(很可能),或者在最坏的情况下您会耗尽内存。

于 2018-07-11T09:45:38.373 回答