gpt4 book ai didi

c++ - 为什么在未计算的操作数中不允许使用 lambda 表达式,但在常量表达式的未计算部分中允许使用 lambda 表达式?

转载 作者:IT老高 更新时间:2023-10-28 22:58:55 25 4
gpt4 key购买 nike

如果我们查看 draft C++ standard 5.1.2 Lambda 表达式2 说(强调我的 future ):

The evaluation of a lambda-expression results in a prvalue temporary (12.2). This temporary is called the closure object. A lambda-expression shall not appear in an unevaluated operand (Clause 5). [ Note: A closure object behaves like a function object (20.8).—end note ]

5.19部分常量表达式2段说:

A conditional-expression is a core constant expression unless it involves one of the following as a potentially evaluated subexpression (3.2), but subexpressions of logical AND (5.14), logical OR (5.15), and conditional (5.16) operations that are not evaluated are not considered [...]

并有以下项目符号:

— a lambda-expression (5.1.2);

那么为什么 lambdas 表达式不允许在未计算的操作数中,但允许在常量表达式的未计算部分?

我可以看到在几种情况下( decltypetypeid )对于未计算的操作数,类型信息不是很有用,因为每个 lambda 都有一个唯一的类型。虽然我们为什么要在常量表达式的未计算上下文中允许它们尚不清楚,但也许是为了允许 SFINAE ?

最佳答案

未计算的操作数排除的核心原因在 C++ Standard Core Language Defect Reports and Accepted Issues #1607. Lambdas in template parameters 中进行了说明。它旨在澄清这一限制,并在 5.1.2 节中说明限制的意图是:

[...] avert the need to deal with them in function template signatures [...]

作为问题文档,当前的措辞实际上有一个漏洞,因为常量表达式允许它们在未评估的上下文中。但它并没有直接说明这种限制的理由。避免名称修改的愿望很突出,您可以推断,避免扩展 SFINAE 也是需要的,因为提议的决议试图加强限制,即使有几个可行的替代方案允许 SFINAE5.1.2段落2的修改版本如下:

A lambda-expression shall not appear in an unevaluated operand (Clause 5 [expr]), in a template-argument, in an alias-declaration, in a typedef declaration, or in the declaration of a function or function template outside its function body and default arguments [Note: The intention is to prevent lambdas from appearing in a signature —end note]. [Note: A closure object behaves like a function object (20.10 [function.objects]). —end note]

此提案已被接受,并在 N3936( see this answer for a link )

为了更明确地讨论避免将 lambdas 作为 未计算的操作数的基本原理。标题为 Rationale for lambda-expressions not being allowed in unevaluated contexts 的讨论关于 comp.lang.cpp.moderated Daniel Krügler 列出了三个原因:

  1. 可能的SFINAE极端扩展案例:

[...]The reason why they became excluded was due to exactly this extreme extension of sfinae cases (you were opening a Pandora box for the compiler)[...]

  1. 在许多情况下它只是无用的,因为每个 lambda 都有一个唯一的类型,给出的假设示例:

    template<typename T, typename U>
    void g(T, U, decltype([](T x, T y) { return x + y; }) func);

    g(1, 2, [](int x, int y) { return x + y; });

    声明和调用中的 lambda 类型不同(根据定义),因此这是行不通的。

  2. Name mangling也成为一个问题,因为一旦您在函数签名中允许 lambda ,则 lambda 的主体也必须被破坏。这意味着要制定规则来破坏每一个可能的语句,这至少对某些实现来说是个负担。

关于c++ - 为什么在未计算的操作数中不允许使用 lambda 表达式,但在常量表达式的未计算部分中允许使用 lambda 表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22232164/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com