我正在尝试学习可变参数模板和函数。我不明白为什么这段代码不能编译:
template<typename T>
static void bar(T t) {}
template<typename... Args>
static void foo2(Args... args)
{
(bar(args)...);
}
int main()
{
foo2(1, 2, 3, "3");
return 0;
}
当我编译失败并出现错误:
Error C3520: 'args': parameter pack must be expanded in this context
(在函数 foo2
中)。
最佳答案
可能发生包扩展的地方之一是 braced-init-list。您可以通过将扩展放在虚拟数组的初始化列表中来利用这一点:
template<typename... Args>
static void foo2(Args &&... args)
{
int dummy[] = { 0, ( (void) bar(std::forward<Args>(args)), 0) ... };
}
更详细地解释初始化器的内容:
{ 0, ( (void) bar(std::forward<Args>(args)), 0) ... };
| | | | |
| | | | --- pack expand the whole thing
| | | |
| | --perfect forwarding --- comma operator
| |
| -- cast to void to ensure that regardless of bar()'s return type
| the built-in comma operator is used rather than an overloaded one
|
---ensure that the array has at least one element so that we don't try to make an
illegal 0-length array when args is empty
Demo .
在 {}
中扩展的一个重要优势是它保证了从左到右的评估。
使用 C++17 fold expressions , 你可以写
((void) bar(std::forward<Args>(args)), ...);
关于c++ - 可变参数模板包扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25680461/