varadic模板参数的模板类型数组

时间:2018-05-14 14:25:25

标签: c++ c++11 templates variadic-functions

我正在为自己创建一个库,其中包含我经常使用的功能和宏,并且不想经常重新键入或复制/粘贴(有时长达数百行)。我在旧项目中有一大块代码,我必须不断地复制和粘贴,然后更改所有变量名称以适合我当前的项目。我想将代码块转换为库中的函数。

大量的代码格式输出到一个盒子中,所以如果输出太长,它不会破坏我可能拥有的任何边界或直接到控制台的边缘(困扰我)。用户传递框的左上角,并提供文本不应传递的右边缘的x坐标。其余参数是要输出的变量或文字。代码块将所有变量和文字放入一个大字符串中,然后由char输出char,直到输出到达x边界。然后输出继续在左上角的x坐标和一行向下。

为了使其工作,该函数必须具有一个varadic模板,以允许多种类型的输出的可变数量(类似于cout << "I have " << 4.5 << " cookies and " << 2 << " friends.")。

模板已完成并且一直有效,直到我尝试创建模板类型的数组并初始化它。

template<typename ...Inputs>
void textBox(int x, int y, int xBoundary, const Inputs&... things) {
    Inputs arr[sizeof...(things)] = {things...};
}

此时我收到此错误:parameter packs not expanded with '...' Note: 'Inputs'

之前我使用过这种类型的东西,但是所有输入都是该函数的相同类型,所以我可以很容易地做到这一点:

template<typename ...Inputs>
void textBox(int x, int y, int xBoundary, const Inputs&... things) {
    std::string arr[sizeof...(things)] = {things...};
}

除非用户尝试传递字符串以外的其他内容,否则不会出现任何错误,因此我知道我的错误与制作模板类型的数组有关。任何帮助,将不胜感激!

1 个答案:

答案 0 :(得分:3)

数组需要包含相同类型的元素 - 它们不是异构数据结构。在您的情况下,Inputs是一个包含所有未展开的things...类型的包,这就是您收到错误的原因。

改为使用std::tuple,这是一个异构容器:

std::tuple<std::decay_t<Inputs>...> tuple{things...};

std::make_tuple

auto tuple = std::make_tuple(things...);

在C ++ 17中,由于类模板参数推导,模板参数可能会被省略:

std::tuple tuple{things...};

如果您要迭代things...,最好不要将它们放在std::tuple中。在C ++ 17中,您可以使用 fold表达式来打印所有这些:

(std::cout << ... << things);

在C ++ 11中,您可以定义伪递归可变参数模板:

template <typename T>
void print(const T& x)
{
     std::cout << x; 
}  

template <typename T, typename... Rest>
void print(const T& x, const Rest&... rest)
{
     print(x);
     print(rest...);
}