简体   繁体   English

`decltype` 的广义 lambda 在 lambda 体内捕获 - gcc 与 Z2C5517DB7BC397CEF9A7754FFZA1

[英]`decltype` of generalized lambda capture inside body of a lambda - gcc vs clang

Consider the following code:考虑以下代码:

#include <type_traits>

int main()
{
    auto l = [k = 0]
    {
        static_assert(std::is_same_v<decltype(k), int>);
    };
}
  • clang++ (10.x and trunk) happily compiles the code above. clang++ (10.x 和trunk)愉快地编译了上面的代码。

  • g++ (10.x and trunk) fails to compile the code above with the following error: g++ (10.x 和trunk)无法编译上面的代码并出现以下错误:

     error: static assertion failed 10 | static_assert(std::is_same_v<decltype(k), int>); | ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~

    Apparently, g++ believes that decltype(k) evaluates to const int .显然, g++认为decltype(k)评估为const int

live example on godbolt.org godbolt.org 上的实时示例

Since the type of the data member k should be deduced from 0 (which is a plain, non- const , int ), I think that this is a g++ bug.由于数据成员k的类型应该从0推导出来(这是一个普通的、非constint ),我认为这是一个g++错误。 In my mental model, the only thing that is const is the operator() of the lambda, but not the synthesized data member k .在我的心理 model 中,唯一的const是 lambda 的operator() ,而不是合成数据成员k

  • Is my assessment correct?我的评估是否正确?

  • What does the standard say?标准是怎么说的?

The standard is rather explicit in this case.在这种情况下,标准相当明确。 [expr.prim.lambda.capture]/6 : [expr.prim.lambda.capture]/6

An init-capture without ellipsis behaves as if it declares and explicitly captures a variable of the form “ auto init-capture;没有省略号的init-capture的行为就好像它声明并显式捕获了“ auto init-capture; ”形式的变量。 ” whose declarative region is the lambda-expression 's compound-statement , [...] ”,其声明区域是lambda-expression复合语句,[...]

so your code is (roughly - see the rest of the quote above to see how the two differ) equivalent to the following, which gcc accepts!所以你的代码(大致 - 请参阅上面引用的 rest 以了解两者有何不同)等同于以下内容, gcc 接受! :

auto k = 0;
auto l = [k]
{
    static_assert(std::is_same_v<decltype(k), int>);
};

So who's right?那么谁是对的呢? For that we see that the type of the k , which is int since auto deduces to int for 0 .为此,我们看到k的类型,它是int ,因为auto推断为int0

Then it is only a matter of looking at [dcl.type.decltype]/1.3 which says:然后只需查看[dcl.type.decltype]/1.3 即可,它说:

[...] if E [ the expression inside decltype ] is an unparenthesized id-expression [...], decltype(E) is the type of the entity named by E . [...] 如果E [ decltype中的表达式] 是一个未加括号的id 表达式[...],则decltype(E)是由E命名的实体的类型。

The type of the entity k is int .实体k的类型是int So gcc is wrong.所以 gcc 是错误的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM