c++ - 非常量复制构造函数可以用 C++17 编译
问题描述
我想知道为什么下面的代码不能用 C++14 编译,但用 C++17 编译得很好。自 C++17 以来有什么可以改变的想法吗?事情当然是关于 A 类的非常量复制构造函数。我使用的是 VS 2019。这段代码是否有效?
class A {
public:
A() { }
A(A& a) { }
};
A fun() {
A a;
return a;
}
int main()
{
A a = fun();
}
来自编译器的消息:
- A 类没有合适的复制构造函数
- 初始化无法从 A 转换为 A
- 由于不明确的复制构造函数或没有可用的复制构造函数,无法复制构造类 A
解决方案
fun()
是一个 prvalue 类型A
,所以A a = fun();
意味着它a
是函数调用的结果对象,没有中间临时对象。
这方面的文字在 C++17 [basic.lval]/2 中:
prvalue的结果对象是prvalue初始化的对象;
对等来说也是一样的A a = A(A(A(A(A(fun())))));
——所有纯右值都a
作为它们的结果对象。
return 语句的行为在 [stmt.return]/2 中:
该
return
语句通过操作数的复制初始化 (11.6) 来初始化(显式或隐式)函数调用的泛左值结果或纯右值结果对象。
a
结果对象可以通过(的局部变量)的复制初始化成功初始化,fun
因为这是一个非常量左值,因此采用非常量左值引用的复制构造函数确实绑定到它。
在 C++17 之前fun()
的返回值是一个临时对象,然后 main 是从临时对象a
复制/移动构造的,省略是可选的(但需要存在有效的构造函数)。
推荐阅读
- postgresql - 校验和和整页图片有什么关系?
- html - 导航无法正确浮动
- sql-server - 从两个表中都存在记录的带有子查询的 2 个表中选择列
- php - 使用 python 将图像 blob 插入 MySQL 数据库并检索 blob 以使用 PHP 显示图像
- c++ - 结构中的动态数组长度
- lstm - Keras LSTM 模型数据重塑
- java - ImageView 条件替代方案 (Android Studio)
- firebase - 使用二维码从 Firebase 存储下载
- python - 在 Pandas 中计算 Rolling Geomean 窗口,就像在 EXCEL 中计算一样
- python - 如果数字是 n 的倍数 - Python