【问题标题】:The validity of lambda expression with omitted parameter list in C++23C++23中省略参数列表的lambda表达式的有效性
【发布时间】:2021-06-24 06:00:11
【问题描述】:

根据cppreference,gcc和clang最近都完成了P1102R2("Down with ()!")的实现,这意味着我们可以在C中更简洁地定义lambda表达式++23.

但我发现它们与某种形式不一致:

auto l = []<auto> noexcept requires true {};

clang 接受这种形式,gcc rejects 它的语法。

我应该信任哪个编译器?这个 lambda 在 C++23 中是格式正确还是格式错误?

更新:

可能是迫于舆论压力,我举报后五天内clang迅速修复了49736

当我进一步尝试时,我偶然发现 gcc 也拒绝了以下有效表单,这让我报告了 99850 并在 2 周后修复。

auto l = []<auto> requires true -> void {};

【问题讨论】:

  • 看起来这个 lambda 没有任何实际应用。添加 language-lawyer 标签可能是个好主意。
  • 我不相信任何 C++23 功能的实现来自一个甚至还没有完成 C++20 的编译器。另外,您甚至会使用什么命令行选项来访问它?
  • @NicolBolas GCC 和 Clang 中继了解-std=c++2b
  • “也许是因为舆论的压力”——+1 只是为了那个笑话。

标签: c++ lambda language-lawyer c++23


【解决方案1】:

感谢您提醒我这个功能是多么无意义。

正确答案是:不,这不是一个格式良好的 lambda。语法定义在[expr.prim.lambda.general]:

在我们的例子中,首先我们有:

[]<auto> noexcept requires true {};
  • []lambda-introducer
  • &lt;auto&gt; 匹配 &lt;template-parameter-list&gt; 现在我们知道我们是第二类 lambda-expression。所以从语法上讲,我们需要跟随一个 requires-clause(可选),然后是一个 lambda-declarator,然后是一个 compound-statement
  • noexcept 不匹配 requires-clause,所以现在我们正在解析 lambda-declaratorlambda-declarator 可以以 (parameter-declaration-clause) 开头,但我们没有那个,所以我们只是在寻找 lambda-specifiers。我们使用 noexcept 作为 noexcept-specifier 的一部分。
  • requires true 不适合 attribute-specifier-seqtrailing-return-type 所以我们都没有,现在我们已经完成了 lambda -specifiers 这样我们就完成了 lambda-declarator。此时,我们正在寻找一个复合语句。但我们没有,所以这是一个错误。

基本上,您可以在两个位置放置 requires-clause:直接在模板参数之后,或者,如果我们有函数参数,则在 之后函数参数之后的 lambda 说明符。所以这行得通:

[]<auto> requires true noexcept {};

就像这样:

[]<auto>() noexcept requires true {};

就像这样:

[]<auto> requires true () noexcept requires true { };

但不是 OP 中的那个。

另外,不要写这个。

【讨论】:

  • 我今天早上为 llvm 提交了bug report,但我不能 100% 确定它应该是格式错误的。谢谢你让我知道我是对的。
  • 另外一点:定义它会消除疣,使语言更规则,因此应该定义它吗?不过,人为的例子并不令人惊讶。
  • @Deduplicator 应该吗?我的意思是,如果你已经在编写模板参数 一个 noexcept 说明符 一个 requires 子句,那么你真的会因为必须这样做而受到伤害吗?提供额外的()?
  • @Deduplicator: 用一个复杂的语法来让一个非空的 lambda-specifiers 区分两个潜在的 requires-clause 根本不值得i>s.
  • 导致当前规则的观察结果是 requires 子句要么约束显式模板参数列表,要么约束显式函数参数列表。因此,一个显式的&lt;&gt; 列表后面可以跟一个 requires 子句,一个显式的() 列表后面可以跟一个 requires 子句。如果省略显式列表,则不能为其包含 requires 子句。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-06
  • 1970-01-01
相关资源
最近更新 更多