[英]`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
推导出来(这是一个普通的、非const
、 int
),我认为这是一个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
推断为int
为0
。
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 insidedecltype
] is an unparenthesized id-expression [...],decltype(E)
is the type of the entity named byE
.[...] 如果
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.