Fed*_*dor 23 c++ language-lawyer lvalue-to-rvalue c++20
考虑一个 C++20 程序,其中函数中foo有一个结构化绑定auto [y]。函数返回y,它被转换为对象类型A。A可以从右值引用的常量引用构造。
#include <tuple>
#include <iostream>
struct A {
A(const int &) { std::cout << "A(const int &) "; }
A(int &&) { std::cout << "A(int &&) "; }
};
A foo() {
auto [y] = std::make_tuple(1);
return y;
}
int main() { foo(); }
Run Code Online (Sandbox Code Playgroud)
根据C++20语言标准应该选择哪一个构造函数?
Clang 选择A(const int &)和 GCC 选择A(int &&),演示:https : //gcc.godbolt.org/z/5q779vE6T
是否有一个编译器不支持这方面的标准?
我相信 Clang 是正确的。
TL;DR:一些左值可以隐式移动,但结构化绑定不是这样的左值。
结构化绑定声明引入标识符列表的标识符, , ,...作为结构化绑定的名称。
v0v1v2
每个都是类型左值的名称,该左值引用绑定到的对象;引用的类型是.
viTiriri
return命名为隐式可移动实体,则它可以在语句中移动:的隐式可动实体是自动存储持续时间的变量,它是任一的非易失性对象或一个rvalue参照非易失性对象类型。在以下复制初始化上下文中,在尝试复制操作之前首先考虑移动操作:
- 如果表达的
return([stmt.return])或co_return([stmt.return.coroutine])语句是一个(可能是括号)ID-表达名称隐式可动实体主体或声明参数声明子句的最里面的封闭函数或lambda 表达式,或- [...]
实体是值、对象、引用或[或]结构化绑定[...]。
所以我相信结构化绑定不能被隐式移动。
如果y是一个对象或引用,那么它将在return y;.
编辑:编写的 C++17 指定元组成员的结构化绑定是引用。这已由CWG 2313纠正。
| 归档时间: |
|
| 查看次数: |
336 次 |
| 最近记录: |