C++ 将变量函数模板的每个参数传递给返回void的函数
根据找到的配方,我写了以下内容:C++ 将变量函数模板的每个参数传递给返回void的函数,c++,templates,c++11,variadic-templates,C++,Templates,C++11,Variadic Templates,根据找到的配方,我写了以下内容: 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; } 这个问题在引用的帖子中被问到,但没
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;
}
这个问题在引用的帖子中被问到,但没有得到任何回答
temp
将std::initializer\u list
填充零,这是由于逗号运算符规则(将计算所有表达式,但只使用最后一个表达式,因此,将为每个参数调用函数printInt
,并为每个参数将0放入初始值设定项列表)()
用于包扩展,因此,..
将应用于full expression,void()
用于保护构造不受类重载运算符的影响(感谢Quentin),您还可以使用以下
{((void)printInt(args), 0)...};
而且,使用它会更好
{0, ((void)printInt(args), 0)...};
对于初始值设定项列表
中的至少一个元素(因此您可以无参数调用f
)
(void)temp代码>要标记未使用的变量,请参阅以下详细信息:
这个答案太简洁了。我不明白1到底发生了什么:圆括号和
void()
的作用是什么?另外,对于2,为什么编译器不抱怨语句对(void)temp没有影响
?void()
是用来保护构造不受类重载操作符的影响,
@永远是迂腐的,可能有;)printInt
被称为unqualified,您不能保证Args
都是int
s,因此您可能会通过ADL发现一些奇怪的东西:P(解决这个问题的方法可能是通过一个限定的调用来抑制ADL。)@MeirGoldenberg当然!类可以重载运算符、
、逗号运算符。假设printInt(arg)
返回Foo
,那么如果存在重载的条形运算符(Foo,int)
,它将被(printInt(args),0)
调用。如果对于每个可能的Foo
来说Bar
并不总是相同的类型,那么您最终会尝试将不同类型的对象填充到相同的std::initializer\u列表中,这是一个错误。@MeirGoldenberg现在,解决方案:void()
并不是一个完全空的表达式强制转换(没有空表达式),但结果是一样的:您获得类型为void
的表达式。而且不可能构造一个重载的操作符(Foo,void)
或操作符(void,int)
。因此,通过插入void
表达式,您可以确定使用的是内置的逗号运算符。
{((void)printInt(args), 0)...};
{0, ((void)printInt(args), 0)...};