【发布时间】:2021-06-11 22:49:10
【问题描述】:
案例 1:
在 lambda noexcept 说明符中考虑以下包扩展:
template <bool... B>
auto g() {
([]() noexcept(B) {}, ...);
}
Clang 和 MSVC 接受此代码,但 GCC rejects 带有:
error: expansion pattern '<lambda>' contains no parameter packs
这是一个有效的代码吗?我应该信任哪个编译器?
案例 2:
考虑 lambda requires-clause 中的以下包扩展:
template <bool... B>
auto g() {
([](auto) requires(B) {}, ...);
}
在这种情况下,Clang 和 MSVC 仍然接受此代码,并且 GCC rejects 它带有相同的错误消息。这只是同一个错误吗?
案例 3:
考虑 lambda 模板列表中的以下包扩展:
template <typename... Args>
void g(Args...) {
([]<Args>(){}, ...);
}
这次三个编译器all reject出现同样的错误信息:
expansion pattern '<lambda>' contains no parameter packs
与案例 1 相比有什么不同吗?或者这是一个常见的错误?
更新:
【问题讨论】:
-
这三个都应该被接受;如果他们不这样做,我会认为这是标准中的错误。它们是每个表达式,这些表达式(在某种递归级别)包含一个参数包,并且这些包一旦扩展就有意义。但是,指定参数包如何扩展是一件很痛苦的事情,而且我相信标准中存在一些错误,导致它们无法正常工作。 (当然,
f(...)调用可能是 UB(或者可能不是,我必须看看空 lambda 和...是如何交互的),但这并不重要) -
@Yakk-AdamNevraumont - 你确定(这是正确的)关于第三种情况吗?我的意思是:
[]<Args>(){}是什么?不应该是[]<typename Args>(){},在那种情况下,定义一个新的typename模板参数,隐藏函数Args列表并且无法解包? -
@max66 非类型模板参数
-
@Yakk-AdamNevraumont - 呃...你是对的。
-
这个有趣问题的状态更新:1) 在 g++ 11.1 中已修复。 2) 在 g++ 11.1 中未修复,因此与 1 中的错误不同。3) 在 MSVC 19.29 中修复。
标签: c++ lambda language-lawyer variadic-templates c++20