C++23中省略参数列表的lambda表达式的有效性

32
根据 cppreference 的说法,gcc和clang均已完成对“Down with ()!”的实现,这意味着我们可以在C++23中更简洁地定义lambda表达式。

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

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

clang接受这种形式,而gcc则拒绝其语法。

我应该信任哪个编译器?在C++23中,这个lambda是良好形式还是不良形式?

更新:

也许是因为舆论的压力,我报告后,clang在五天内迅速修复了49736 问题。

随着我的进一步尝试,我意外发现gcc还拒绝了以下有效的形式,这促使我报告99850 并在两周后解决了问题。

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

这个 lambda 看起来没有任何实际应用。添加 language-lawyer 标签可能是一个好主意。 - super
我不会信任那些连C++20都没有完成的编译器实现C++23的任何功能。此外,你甚至会使用什么命令行选项来访问它呢? - Nicol Bolas
@NicolBolas GCC和Clang的主干版本都支持“-std=c++2b”。 - HolyBlackCat
1
也许是因为公众舆论的压力 -- 仅因那个笑话加1分。 - Yakk - Adam Nevraumont
1个回答

34

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

正确的答案是:不,那不是一个良好形式的 lambda 表达式。语法在 [expr.prim.lambda.general] 中定义:

enter image description here

针对我们的情况,首先我们有:

[]<auto> noexcept requires true {};
  • []lambda 引入符
  • <auto> 匹配 <template-parameter-list>,现在我们知道我们是第二种 lambda 表达式。从语法上讲,我们需要跟随一个 requires 子句(可选),然后是一个 lambda 声明符,然后是一个 复合语句
  • noexcept 不匹配 requires 子句,所以现在我们正在解析 lambda 声明符。一个 lambda 声明符 可以以 (parameter-declaration-clause) 开始,但我们没有这个,所以我们只需要查找 lambda 限定符。我们将 noexcept 作为 noexcept 限定符 的一部分来使用。
  • requires true 既不符合 attribute-specifier-seq 也不符合 trailing-return-type,因此我们两者都没有,现在我们已经完成 lambda 限定符,因此我们已经完成了 lambda 声明符。此时,我们正在寻找一个 复合语句。但是我们没有这个,所以这是一个错误。

基本上,有两个位置可以放置 requires 子句:要么直接放在模板参数后面,要么在如果我们有函数参数之后的 lambda 限定符之后。因此,这个可以工作:

[]<auto> requires true noexcept {};

就像这样:

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

就像这样:

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

但不是OP中的那个。

另外,请不要写这个。


3
今早我为LLVM提交了一个错误报告,但我不确定它是否应该被认为是非法的。感谢您让我知道我是正确的。 - 康桓瑋
另外一个观点是:如果将其定义清晰,能否去除一些问题,使语言更加规范化,因此应该进行定义?虽然这些例子有些牵强附会,但并不令人惊讶。 - Deduplicator
@Deduplicator 应该吗?我的意思是,如果你已经到了编写模板参数、noexcept-specifier和requires-clause的地步,那么再提供一个额外的()会对你造成什么伤害呢? - Barry
@Barry 这会使它更规则化吗?它应该做什么是不含糊的吗?最多只有一个简单的解决方法会降低优先级。 - Deduplicator
2
@Deduplicator:为了使非空的lambda-specifiers区分两个潜在的requires-clause,制定复杂的语法并不值得考虑。 - Davis Herring
5
导致当前规则的观察结果是,requires从句要么约束显式模板参数列表,要么约束显式函数参数列表。因此,显式的<>列表可以跟随一个requires从句,显式的() 列表也可以跟随一个requires从句。如果省略了显式列表,则无法包含requires从句。 - Richard Smith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接