C++23中省略参数列表的lambda表达式的有效性
The validity of lambda expression with omitted parameter list in C++23
根据最近cppreference, both gcc and clang have completed the implementation of P1102R2 ("Down with ()!"),这意味着我们可以在C++23中更简洁地定义lambda表达式。
但我发现它们与某种形式不一致:
auto l = []<auto> noexcept requires true {};
clang 接受这种形式,而 gcc rejects 它的语法。
我应该信任哪个编译器?这个 lambda 在 C++23 中是良构还是病态的?
更新:
可能是迫于public意见的压力,clang在我举报后五天之内就迅速修复了49736
随着我进一步尝试,我无意中发现gcc也拒绝了以下有效形式,这让我报告了99850并在2周后修复了
auto l = []<auto> requires true -> void {};
感谢您提醒我这个功能是多么毫无意义。
正确答案是:不,这不是一个格式正确的 lambda。语法定义在 [expr.prim.lambda.general]:
在我们的例子中,首先我们有:
[]<auto> noexcept requires true {};
[]
是 lambda 介绍人
<auto>
匹配 <template-parameter-list>
现在我们知道我们是第二种 lambda 表达式。所以在语法上,我们需要跟随一个 requires-clause(可选)然后是一个 lambda-declarator 然后是一个 compound -声明.
noexcept
不匹配 requires-clause,所以现在我们正在解析一个 lambda-declarator。 lambda-declarator 可以以 (parameter-declaration-clause)
开头,但我们没有,所以我们只是在寻找 lambda-specifiers .我们将 noexcept
作为 noexcept-specifier. 的一部分使用
requires true
不适合 attribute-specifier-seq 或 trailing-return-type 所以这些我们都没有,现在我们完成了 lambda-specifiers,所以我们完成了 lambda-declarator。此时,我们正在寻找 复合语句 。但是我们没有那个,所以这是一个错误。
基本上,有两个地方可以放置 requires-clause:直接在模板参数之后,或者,如果我们有函数参数, 在 lambda-specifiers 之后的函数参数之后。所以这有效:
[]<auto> requires true noexcept {};
就像这样:
[]<auto>() noexcept requires true {};
就像这样:
[]<auto> requires true () noexcept requires true { };
但不是 OP 中的那个。
另外,不要写这个
根据最近cppreference, both gcc and clang have completed the implementation of P1102R2 ("Down with ()!"),这意味着我们可以在C++23中更简洁地定义lambda表达式。
但我发现它们与某种形式不一致:
auto l = []<auto> noexcept requires true {};
clang 接受这种形式,而 gcc rejects 它的语法。
我应该信任哪个编译器?这个 lambda 在 C++23 中是良构还是病态的?
更新:
可能是迫于public意见的压力,clang在我举报后五天之内就迅速修复了49736
随着我进一步尝试,我无意中发现gcc也拒绝了以下有效形式,这让我报告了99850并在2周后修复了
auto l = []<auto> requires true -> void {};
感谢您提醒我这个功能是多么毫无意义。
正确答案是:不,这不是一个格式正确的 lambda。语法定义在 [expr.prim.lambda.general]:
在我们的例子中,首先我们有:
[]<auto> noexcept requires true {};
[]
是 lambda 介绍人<auto>
匹配<template-parameter-list>
现在我们知道我们是第二种 lambda 表达式。所以在语法上,我们需要跟随一个 requires-clause(可选)然后是一个 lambda-declarator 然后是一个 compound -声明.noexcept
不匹配 requires-clause,所以现在我们正在解析一个 lambda-declarator。 lambda-declarator 可以以(parameter-declaration-clause)
开头,但我们没有,所以我们只是在寻找 lambda-specifiers .我们将noexcept
作为 noexcept-specifier. 的一部分使用
requires true
不适合 attribute-specifier-seq 或 trailing-return-type 所以这些我们都没有,现在我们完成了 lambda-specifiers,所以我们完成了 lambda-declarator。此时,我们正在寻找 复合语句 。但是我们没有那个,所以这是一个错误。
基本上,有两个地方可以放置 requires-clause:直接在模板参数之后,或者,如果我们有函数参数, 在 lambda-specifiers 之后的函数参数之后。所以这有效:
[]<auto> requires true noexcept {};
就像这样:
[]<auto>() noexcept requires true {};
就像这样:
[]<auto> requires true () noexcept requires true { };
但不是 OP 中的那个。
另外,不要写这个