可以捕获的实体的声明:它应该产生lambda之外的实体的类型吗?
考虑以下简单的独立代码:
template<typename T>
void foo();
void bar() {
int i;
auto l = [&i]() -> decltype(auto) {
decltype(auto) x = i;
foo<decltype(x)>();
foo<decltype(i)>();
return static_cast<decltype(i)>(i);
};
l();
foo<decltype(l())>();
}
GCC生成以下内容:
bar():
sub rsp, 8
call void foo<int&>()
call void foo<int>()
add rsp, 8
jmp void foo<int>()
Clang生成以下内容:
bar(): # @bar()
push rax
call void foo<int>()
call void foo<int>()
pop rax
jmp void foo<int>() # TAILCALL
MSVC生成以下内容:
void bar(void) PROC ; bar, COMDAT
$LN8:
sub rsp, 40 ; 00000028H
call void foo<int &>(void) ; foo<int &>
call void foo<int &>(void) ; foo<int &>
add rsp, 40 ; 00000028H
jmp void foo<int &>(void) ; foo<int &>
void bar(void) ENDP
似乎所有三个编译器都不同意。哪一个是正确的,C ++标准的哪一部分证实了这一点?
在我看来, exltype(i)
应始终是 int
,并且永远不要 int&amp;
,无论是否被捕获。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
exltype(auto)
在 [dcl.type.auto.deduct]/4 :这意味着
code> nectType(auto)x = i
等效于exltype(i)x = i
。关于decltype(i)
,说明:因此,
exltype(i)
是i
命名的实体类型,即,int
。因此,x
是类型int
的类型,因此,exltype(x)
也是int
。因此,在这种情况下,Clang是正确的。 GCC中的此错误已针对GCC 14( patrick )。但是,似乎此修复会导致海湾合作委员会的另一个错误。如果我们将
i
的类型更改为int&amp;
,则以下代码演示了此问题( godbolt ):遵循与上述相同的推理,在这种情况下,Clang和GCC 13是正确的。
decltype(auto)
is specified in [dcl.type.auto.deduct]/4:This means
decltype(auto) x = i
is equivalent todecltype(i) x = i
. Regardingdecltype(i)
, [dcl.type.decltype]/1.3 states:Thus,
decltype(i)
is the type of entity named byi
, i.e.,int
. Therefore,x
is of typeint
, and consequently,decltype(x)
is alsoint
. Hence, Clang is correct in this case. This bug in GCC has been fixed for GCC 14 (Patrick).However, it appears that this fix causes another bug in GCC. If we change the type of
i
toint&
, the following code demonstrates this issue (Godbolt):Following the same reasoning as above, Clang and GCC 13 are correct in this case.