《C++ Primer 5th》合成移动构造被删除与拷贝构造调用疑问
问题结论
你的理解完全正确,该现象符合C++标准的移动构造重载决议规则。
规则解释
- 当一个类显式定义了拷贝构造函数时,编译器不会为其隐式生成移动构造函数,此时向该类构造函数传入右值时,重载决议会优先匹配可用的构造函数:由于右值可以绑定到
const T&类型的参数,所以拷贝构造函数可以接收右值完成初始化。 - 你为
hasY显式声明= default的移动构造函数时,编译器生成的默认移动构造逻辑会逐成员执行移动初始化:对于Y类型的mem成员,找不到可用的移动构造,就会自动回退调用拷贝构造函数完成初始化,整个过程合法,所以hasY的移动构造不会被标记为删除,不会触发编译报错。 - 《C++ Primer 第5版》的注释对应的是另一种场景:如果
Y的拷贝构造函数的参数是非const左值引用(即Y(Y&)),此时右值无法绑定到非const左值引用,hasY的移动构造找不到合法的方式初始化mem成员,才会被编译器标记为删除,触发编译报错。
验证方法
你可以修改Y的拷贝构造定义来复现书中的报错效果:
struct Y{ Y() = default; Y(Y&){cout << "Y's cpy-ctor\n";} // 去掉const修饰符 };
此时编译代码就会触发hasY移动构造已删除的报错,和书中描述一致。
内容的提问来源于stack exchange,提问作者Itachi Uchiwa
相关产品推荐
相关产品推荐

