Can someone explains me why a parameter can be declared as 'auto ... arg
' in this context (when used in a lambda):
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
Life example.
But not in this (when used in a function):
void func(auto ... arg)
{
}
Life example.
I would be very happy of a detailed explanation with a quotes from the latest ISO C++ draft. Or is this a bug of clang compiler? Because it compiles fine actually under gcc 5.0.
I found the answer by myself. It's stated in 'n4296' at § 5.1.2.5:
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.
This means that something like this:
[](auto ... arg) {}
Is roughly equivalent to:
template<class ... tmp>
ClosureType::operator()(tmp ... arg);
However I don't know why isn't this also allowed in normal functions. Perhaps someone should propose it.