在decltype(auto)的情况下,lambda是否有特殊规定? [英] Is there a special rule for lambda in case of decltype(auto)?

查看:116
本文介绍了在decltype(auto)的情况下,lambda是否有特殊规定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我正确理解此答案,并引用了标准部分

If I understood correctly this answer and referenced standard section [dcl.type.auto.deduct-5], the code:

decltype(auto) a = e;

始终等于

decltype( e  ) a = e;

但是现在出现问题,如果我将lambda表达式而不是e放到decltype(auto):

But now the problem appears if instead of e I put the lambda expression to decltype(auto):

decltype(auto) lambda = [](){};

令我惊讶的是,这在 gcc [expr.prim.lambda#2] (强调我的意思):

This compiles, to my surprise, successfully in both gcc and clang. Reason for the shock I've experienced lays in standard which says specifically that lambda should not occur in unevaluated operand [expr.prim.lambda#2] (emphasis mine):

lambda表达式是一个prvalue,其结果对象称为 关闭对象. lambda表达式不得出现在未评估的值中 操作数,在模板参数中,在别名声明中,在typedef中 声明,或者在函数或函数模板的声明中 在函数主体和默认参数之外.

A lambda-expression is a prvalue whose result object is called the closure object. A lambda-expression shall not appear in an unevaluated operand, 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.

但是正如我提到的,该示例等效于:

But as I mentioned the example would be equivalent to:

decltype([](){}) lambda = [](){};

上面明确编写的代码显然是错误的.当然,我们可以假设decltype中的语句[](){}是一种引用,实际上不是像

The above code written explicitly obviously would be ill-formed. Of course we could assume that the statement [](){} inside decltype is kind of reference that isn't really a reference like in case of structured bindings, but maybe there is a special rule in standard that I've missed covering lambda initializing decltype(auto)?

推荐答案

此答案基于我对相关标准文本的解释.这些部分的意见不明确,因此目前很难知道它们的确切含义.似乎,除了可能的疏忽外,主要的编译器似乎都同意所讨论的定义确实格式正确.

This answer is based on my interpretation of the relevant Standard text. Those sections are not very clear with divided opinions, and thus it is currently hard to know the exact meaning of them. It seems that, excluding a possible oversight, the major compilers seem to agree that the definition in question is indeed well-formed.

此外,我认为听到该定义的格式不正确将非常令人惊讶.

In addition, it is my opinion that it would be very surprising to hear that the definition were ill-formed.

我遭受冲击的原因在于标准,该标准特别指出,lambda不应出现在未经评估的操作数中.[...]

Reason for the shock I've experienced lays in standard which says specifically that lambda should not occur in unevaluated operand [...]

您在哪里看到lambda在未评估的上下文中出现?

Where do you see that a lambda appears in an unevaluated context?

decltype(auto) lambda = [](){};

我看不到,因为没有. lambda用作初始化程序,这是完全合法的.

I don't see it, because there is none. The lambda is used as an initializer, which is completely legal.

现在您可能会感到困惑,因为您似乎认为上述陈述等同于

Now your confusion probably comes about because you seem to think that the above statement is equivalent to

decltype([](){}) lambda = [](){};

严格来说,事实并非如此.如果您查看措辞的语言,则有一个小的差异(由我突出显示):

That's not the case though, strictly speaking. If you look at the language of the wording, there is a small difference (highlighted by me):

如果占位符是decltype(auto) 类型说明符,则T只能是占位符.为T推导的类型是按照[dcl.type.simple]中的描述确定的,因为尽管 edecltype的操作数.

If the placeholder is the decltype(auto) type-specifierT shall be the placeholder alone. The type deduced for T is determined as described in [dcl.type.simple], as though e had been the operand of the decltype.

这里的关键词是 though .只是意味着演绎就好像是decltype(e)一样,这意味着decltype的演绎规则适用于操作数e而不是auto的演绎规则.

The key word here is though. It just means that the deduction happens as if it were decltype(e), meaning that the deduction rules of decltype apply instead of those for auto for the operand e.

在这里,操作数e确实是lambda,但这是完全合法的,因为标准要求行为的行为与相同,就像您将编写decltype([](){})一样,这意味着decltype扣除规则中的一部分适用于lambda.现在[expr.prim.lambda]/2不适用于此处,因为lambda不在未评估的上下文中,因此编译器使用decltype([](){})推导类型实际上是合法的,这意味着必须使用decltype规则λ.

Here, the operand e is indeed the lambda, but that is completely legal, because the Standard mandates that the behavior is the same as if you would have written decltype([](){}), meaning that of the rules of decltype deduction apply for the lambda. Now [expr.prim.lambda]/2 doesn't apply here, because the lambda is not in an unevaluated context, so it is actually legal for the compiler to use decltype([](){}) to deduce the type, meaning that the decltype rules have to be used for the lambda.

当然,如果您编写decltype([](){}),则该程序格式不正确,但如上所述不是这种情况.

Sure, if you write decltype([](){}), the program is ill-formed, but that is not the case here, as mentioned above.

在这种情况下,由于lambda表达式是prvalue,因此推导的类型应该只是lambda的类型.

In this case, because a lambda expression is a prvalue, the deduced type should just be the type of the lambda.

至少我是这样理解的...

At least that's how I understand it...

这篇关于在decltype(auto)的情况下,lambda是否有特殊规定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆