'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);
但是我不知道为什么这在正常功能中也不允许。也许有人应该提出它。
谁能解释一下为什么在此上下文中(在 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);
但是我不知道为什么这在正常功能中也不允许。也许有人应该提出它。