'auto ... arg' 的参数包形式在 lambda 中启用但在函数中没有启用?

Parameter pack form of 'auto ... arg' is enabled in lambda but not in function?

谁能解释一下为什么在此上下文中(在 lambda 中使用时)可以将参数声明为“auto ... arg”:

    auto glambda = [](auto a, auto&& b) { return a < b; }; 
    bool b = glambda(3, 3.14); // OK

    auto vglambda = [](auto printer) { 
        return [=](auto ... ts) { // OK: ts is a function parameter pack 
            printer(std::forward<decltype(ts)>(ts)...);
            return [=]() { printer(ts ...); };
        };
    };

    auto p = vglambda( [](auto v1, auto v2, auto v3) { std::cout << v1 << v2 << v3; } ); 

    auto q = p(1, 'a', 3.14); // OK: outputs 1a3.14 q(); // OK: outputs 1a3.14

生活example.

但不在此(在函数中使用时):

void func(auto ... arg)
{
}

生活example.

我很乐意提供引用最新 ISO C++ 草案的详细解释。或者这是 clang 编译器的错误?因为它实际上在 gcc 5.0 下编译得很好。

我自己找到了答案。在第 5.1.2.5 节的 'n4296' 中有说明:

The closure type for a non-generic lambda-expression has a public inline function call operator (13.5.4) whose parameters and return type are described by the lambda-expression’s parameter-declaration-clause and trailing-return-type respectively. For a generic lambda, the closure type has a public inline function call operator member template (14.5.2) whose template-parameter-list consists of one invented type template parameter for each occurrence of auto in the lambda’s parameter-declaration-clause, in order of appearance. The invented type template-parameter is a parameter pack if the corresponding parameter-declaration declares a function parameter pack (8.3.5). The return type and function parameters of the function call operator template are derived from the lambda-expression’s trailing-return-type and parameter-declarationclause by replacing each occurrence of auto in the decl-specifiers of the parameter-declaration-clause with the name of the corresponding invented template-parameter.

这意味着像这样的事情:

[](auto ... arg) {}

大致相当于:

template<class ... tmp>
ClosureType::operator()(tmp ... arg);

但是我不知道为什么这在正常功能中也不允许。也许有人应该提出它。