我正在尝试学习可变参数的模板和功能。我不明白为什么这段代码无法编译:
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;
}
当我编译它失败并出现错误:
(在
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)), ...);