参数包未使用“...”展开

时间:2015-11-23 10:17:36

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

我有这段代码:

#include <iostream>
using namespace std;

int print(int i)
{
    cout << endl << i;
}

template<typename ...Args>
inline void pass(Args&&...args)
{

}

template<typename ...args>
inline void expand(args&&... a)
{
    print(a) ...; //this doesn't expand
    //pass( print(a)... ); this works
}

int main() {
    expand(1,2,3,4);
    return 0;
}

它会抛出错误:

 In function 'void expand(args&& ...)':
error: expected ';' before '...' token
  print(a) ...;
           ^
parameter packs not expanded with '...':
  print(a) ...;
              ^

为什么需要使用pass()功能?

3 个答案:

答案 0 :(得分:17)

基本上,扩展参数包E...会为包中的每个元素生成一个列表 E1, E2, [...], EN,一个E。此语法结构仅在列表语法正确的位置有效,例如在函数调用,初始化列表等中。包含多个逗号运算符的表达式不计算。

我相信https://docs.oracle.com/javase/tutorial/deployment/jar/build.htmlfold expressions)您可以简单地写一下:

(print(a), ...);

在此表达式中,

  • print(a)是一个带有未扩展参数包的表达式
  • ,是运营商和
  • ...表示正确的折叠展开。

整个表达式的结果是(print(a), ...)将转换为

print(a1) , (print(a2), (print(a3), print(a4))) // (assuming four elements). 

答案 1 :(得分:1)

这也是可行的:

#include <iostream>

void print() {}

template<typename T, typename ... Types>
void print (T firstArg, Types ... args) {
    std::cout << firstArg << "\n";
    print(args...);
}

int main() {
    print("Hello",1337,42.44,"World");
}

Demo

答案 2 :(得分:0)

使用 C++17 和 fold 表达式,上面的代码可以简化如下:

#include <iostream>

template<typename ...args>
inline void print(args&&... a) {
    ((std::cout << a << std::endl), ...);
}

int main() {
    print(1,2,3,4);
    return 0;
}