将可变参数函数模板的每个参数传递给 returns void 的函数
Passing each argument of a variadic function template into a function that returns void
根据 here 找到的食谱,我写了以下内容:
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;
}
两个问题:
这个语法是什么意思:{(printInt(args), void(), 0)...}
?
我添加了行 auto a = temp; temp = a;
以便不会收到有关未使用变量 temp
的警告。有没有更好的办法?
在回复和评论中的解释之后,唯一剩下的问题是:为什么 C++ 不允许这样做:
template <typename... Args>
void f(const Args &... args) {
printInt(args)...;
}
在引用的 post 中提出了这个问题,但没有得到任何答复。
- 这个语法意味着,
temp
将被 std::initializer_list<int>
填充为零,由于逗号运算符规则(所有表达式都将被评估,但只会使用最后一个,因此,函数 printInt
将为每个参数调用并且 0 将被放入每个参数的初始化列表)。
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). 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. 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. If the value of the right
operand is a temporary (12.2), the result is that temporary.
{(printInt(args), void(), 0)...};
()
用于包扩展,因此,...
将应用于完整表达式,void()
用于保护构造免受 类 重载运算符,(谢谢昆汀),你也可以使用以下
{((void)printInt(args), 0)...};
还有,用
会更好
{0, ((void)printInt(args), 0)...};
对于 initializer_list
中的至少一个元素(因此您可以不带参数调用 f
)。
- 您可以使用
(void)temp;
标记变量未使用,这里有更多信息:What does (void) 'variable name' do at the beginning of a C function?
根据 here 找到的食谱,我写了以下内容:
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;
}
两个问题:
这个语法是什么意思:
{(printInt(args), void(), 0)...}
?我添加了行
auto a = temp; temp = a;
以便不会收到有关未使用变量temp
的警告。有没有更好的办法?
在回复和评论中的解释之后,唯一剩下的问题是:为什么 C++ 不允许这样做:
template <typename... Args>
void f(const Args &... args) {
printInt(args)...;
}
在引用的 post 中提出了这个问题,但没有得到任何答复。
- 这个语法意味着,
temp
将被std::initializer_list<int>
填充为零,由于逗号运算符规则(所有表达式都将被评估,但只会使用最后一个,因此,函数printInt
将为每个参数调用并且 0 将被放入每个参数的初始化列表)。
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). 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. 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. If the value of the right operand is a temporary (12.2), the result is that temporary.
{(printInt(args), void(), 0)...};
()
用于包扩展,因此,...
将应用于完整表达式,void()
用于保护构造免受 类 重载运算符,(谢谢昆汀),你也可以使用以下
{((void)printInt(args), 0)...};
还有,用
会更好{0, ((void)printInt(args), 0)...};
对于 initializer_list
中的至少一个元素(因此您可以不带参数调用 f
)。
- 您可以使用
(void)temp;
标记变量未使用,这里有更多信息:What does (void) 'variable name' do at the beginning of a C function?