简体   繁体   English

将可变参数函数模板的每个参数传递给返回void的函数

[英]Passing each argument of a variadic function template into a function that returns void

Based on the recipe found here , I wrote the following: 根据这里找到的配方,我写了以下内容:

void printInt(int a) {std::cout << a << std::endl;}

template <typename... Args>
void f(const Args &... args) {
    auto temp = {(printInt(args), void(), 0)...};
    auto a = temp; temp = a;
}

Two questions: 两个问题:

  1. What does this syntax mean: {(printInt(args), void(), 0)...} ? 这个语法是什么意思: {(printInt(args), void(), 0)...}

  2. I added the line auto a = temp; temp = a; 我添加了行auto a = temp; temp = a; auto a = temp; temp = a; in order to not get a warning about the unused variable temp . 为了不获得有关未使用的变量temp的警告。 Is there a better way? 有没有更好的办法?


After the explanations in the reply and the comments, the only question that remains is: why doesn't C++ allow for this: 在回复和评论中的解释之后,剩下的唯一问题是:为什么C ++不允许这样做:

template <typename... Args>
void f(const Args &... args) {
    printInt(args)...;
} 

This question was asked in the cited post, but did not receive any answer. 引用的帖子中提到了这个问题,但未收到任何答复。

  1. This syntax means, that temp will be std::initializer_list<int> filled with zeros, due comma operator rules (all expressions will be evaluated, but only last will be used, so, function printInt will be called for each argument and 0 will be putted to initializer list for each argument). 这个语法的意思是, temp将被std::initializer_list<int>填充零,由于逗号运算符规则(将评估所有表达式,但只使用last,因此,将为每个参数调用函数printInt ,0将被推到每个参数的初始化列表中)。

N4296 5.19/1 N4296 5.19 / 1

A pair of expressions separated by a comma is evaluated left-to-right; 用逗号分隔的一对表达式从左到右进行评估; the left expression is a discarded- value expression (Clause 5). 左表达式是丢弃值表达式(第5条)。 87 Every value computation and side effect associated with the left expression is sequenced before every value computation and side effect associated with the right expression. 87在与右表达式关联的每个值计算和副作用之前,对与左表达式相关联的每个值计算和副作用进行排序。 The type and value of the result are the type and value of the right operand; 结果的类型和值是右操作数的类型和值; the result is of the same value category as its right operand, and is a bit-field if its right operand is a glvalue and a bit-field. 结果与右操作数具有相同的值类别,如果右操作数是glvalue和位域,则是一个位域。 If the value of the right operand is a temporary (12.2), the result is that temporary. 如果右操作数的值是临时值(12.2),则结果是临时值。

{(printInt(args), void(), 0)...};

() is for pack expansion, so, ... will be applied to full expression, void() is here to shield the construct against classes overloading operator , (thanks Quentin), you can also use following ()是用于包扩展,所以, ...将应用于完整表达式, void()在这里屏蔽构造对类重载操作符,(感谢Quentin),你也可以使用以下

{((void)printInt(args), 0)...};

Also, it will be better to use 此外,它会更好用

{0, ((void)printInt(args), 0)...};

for at least one element in initializer_list (so you can call f without arguments). 对于initializer_list中的至少一个元素(所以你可以不带参数调用f )。

  1. You can use (void)temp; 你可以使用(void)temp; to mark variable unused, here is more info: What does (void) 'variable name' do at the beginning of a C function? 标记变量未使用,这里有更多信息: (void)'变量名'在C函数的开头做了什么?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM