参数包未使用"..."展开

q12*_*26y 12 c++ variadic-functions variadic-templates c++14

我有这个代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

它抛出一个错误:

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

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

Tar*_*ama 17

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

我相信使用折叠表达式(N4295:折叠表达式(Andrew Sutton,Richard Smith)),你将能够简单地写:

(print(a), ...);
Run Code Online (Sandbox Code Playgroud)

在这个表达中,

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

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

print(a1) , (print(a2), (print(a3), print(a4))) // (assuming four elements). 
Run Code Online (Sandbox Code Playgroud)

  • 现在你让我想知道为什么会出现这种情况,因为 `foo(), foo();` 是一个有效的表达式。 (2认同)
  • 我明白那个。我想知道为什么包扩展仅限于列表而不允许用于语句。 (2认同)
  • @RichardHodges 老实说,我不确定。我认为当我们得到折叠表达式时这一切都会得到解决。 (2认同)

Nik*_*iou 6

包扩展只能在包扩展上下文中发生.这些基本上是:

  • 支持初始化
  • 初始化列表
  • 聚合初始化
  • 函数调用
  • 数组初始化

其中更容易使用的是最后一个:

#include <iostream>
using namespace std;
int print(int i)
{
    cout<<endl<<i;
    return 0;
}

template<typename ...args>
inline void expand(args&&... a)
{
    using expander = int[]; 
    (void)expander{0, ((void)print(a), 0)...}; 
}

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

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Demo

  • 我在嘲笑C++.这种语法是做这个简单事情的"最简单"的方法是可笑的. (5认同)