我正在尝试学习可变参数的模板和功能。我不明白为什么这段代码无法编译:

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)), ...);

09-10 04:24
查看更多