我正在为自己创建一个库,其中包含我经常使用的功能和宏,并且不想经常重新键入或复制/粘贴(有时长达数百行)。我在旧项目中有一大块代码,我必须不断地复制和粘贴,然后更改所有变量名称以适合我当前的项目。我想将代码块转换为库中的函数。
大量的代码格式输出到一个盒子中,所以如果输出太长,它不会破坏我可能拥有的任何边界或直接到控制台的边缘(困扰我)。用户传递框的左上角,并提供文本不应传递的右边缘的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...};
}
除非用户尝试传递字符串以外的其他内容,否则不会出现任何错误,因此我知道我的错误与制作模板类型的数组有关。任何帮助,将不胜感激!
答案 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...);
}