在下列程式码中:
int foo() {
int a = 5;
auto l = [&r = std::move(std::as_const(a))] { return r; };
return l();
}
clang编译正常
gcc产生错误。
error: cannot capture 'std::move<const int&>((* & std::as_const<int>(a)))' by reference
我需要社区的帮助来从C标准的Angular 讨论这个案例:在C20中谁是正确的以及为什么正确。
从[expr.prim.lambda.capture]中,我不清楚该子句是否:
不带省略号的init-capture的行为就像声明并显式捕获“auto init-capture”形式的变量一样
是否意味着clang是正确的?如果是,为什么删除as_const会使两者都出错?
code example on godbolt
1条答案
按热度按时间zz2j4svz1#
这似乎是一个愚者bug。init-capture的行为应该像声明一个带有
auto
前缀的相应变量一样,然后捕获它(与标准中的引用完全相同):这会将
auto
推导为const int
,使得变量具有const int&
类型,并且初始化将是合式的,因为初始化器是const int
类型的右值,const
左值引用可以直接绑定到该右值。然而,
std::move
在这里没有任何作用,没有它的结果也是一样的。(const
类型上的std::move
基本上没有任何意义。)如果没有
as_const
,则会失败,因为auto
将被推导为int
,因此变量的类型为int&
。然后,您尝试从右值(std::move
的结果)初始化它,这在初始化非const
左值引用时是不允许的。