C++ 11可变参数模板和逗号分隔表达式等价

Pau*_*aul 4 c++ variadic-templates c++11

在可变参数模板中,...运算符将参数包扩展为一系列以逗号分隔的参数(最简单的形式).我的问题是:为什么调用some_function()为多个参数逗号分隔的作品,并用...运算符调用它不?

我在谈论这段代码:

template<typename... Args> inline void expand(Args&&... args) 
{
   some_function(22),some_function(32); // Works
   some_function(args)...; // Doesn't work - ERROR
}
Run Code Online (Sandbox Code Playgroud)

这两条线不应该产生类似的输出吗?

Arn*_*rtz 6

正如在另一个答案中所说,通过扩展参数包得到的逗号不是逗号oparator,而是参数列表.将参数列表作为表达式显然是一个错误.由于您不需要函数的返回值,您可以尝试以下行:

template <class... T>
void ignore(T&&...) {}

template<typename... Args> inline void expand(Args&&... args) 
{
   ignore(some_function(args)...); 
}
Run Code Online (Sandbox Code Playgroud)

如果some_function返回void,则包扩展将不起作用,因为您不能为函数提供void"值".您可以使用some_function逗号运算符返回值或链接每次调用:

template<typename... Args> inline void expand(Args&&... args) 
{
   ignore( (some_function(args),true)...); 
   //or:
   bool b[] = {(some_function(args),true)...};
}
Run Code Online (Sandbox Code Playgroud)


fil*_*mor 5

因为在第一种情况下,你没有逗号分隔的参数,而是使用逗号运算符,一个完全不同的野兽.

您可以expand递归地实现该函数:

inline void expand() {}

template<typename T, typename... Args>
inline void expand(T&& head, Args&&... tail)
{
    some_function(head);
    expand(tail...);
}
Run Code Online (Sandbox Code Playgroud)

  • 另一个解决方案是在括号内的初始化列表中展开它.即`expand foo {args ...};` (3认同)