Kon*_*rov 6 c++ language-lawyer c++20
在下面的代码中:
int foo() {
int a = 5;
auto l = [&r = std::move(std::as_const(a))] { return r; };
return l();
}
Run Code Online (Sandbox Code Playgroud)
clang 编译得很好
gcc 产生错误。
error: cannot capture 'std::move<const int&>((* & std::as_const<int>(a)))' by reference
Run Code Online (Sandbox Code Playgroud)
我需要社区的帮助来从 C++ 标准的角度争论这个案例:谁在 C++20 中是正确的以及为什么到底。
从 [expr.prim.lambda.capture] 我不清楚这个子句是否:
不带省略号的 init-capture 的行为就像它声明并显式捕获“auto init-capture”形式的变量一样
意味着 clang 是对的?如果是,那么为什么删除 as_const 会使这两者都出错?
似乎是 GCC 的错误。init-capture 的行为应该就像声明带有auto前缀的相应变量一样,然后捕获该变量(与标准中的引用完全相同):
auto &r = std::move(std::as_const(a));
Run Code Online (Sandbox Code Playgroud)
这将推断auto变量const int具有类型const int&并且初始化将是格式良好的,因为初始值设定项是左值引用可以直接绑定到的类型的右const int值const。
但是std::move这里没有任何效果,如果没有它,结果将是相同的。(std::move在const 类型上基本上没有意义。)
它会失败,as_const因为 thenauto将被推导为恰好int使变量具有 type int&。然后,您尝试从右值( 的结果std::move)初始化它,这在初始化非左值引用时是不允许的const。
| 归档时间: |
|
| 查看次数: |
114 次 |
| 最近记录: |