为何返回类型为A的C++函数可返回std::move生成的A&&?
为什么返回
A&&到返回类型为A的函数能正常编译? 我在学习右值引用时,在Compiler Explorer测试代码遇到了疑问。以下是两个示例代码片段:
第一个代码片段:
class A { public: A&& func(A& rhs) { //return rhs; return std::move(rhs); //returning A&& } };
对比第二个代码片段:
class A { public: A func(A& rhs) { //return rhs; return std::move(rhs); //returning A&& } };
第二个片段中,func的返回类型为A,但实际返回的是std::move(rhs)生成的A&&类型值,我原本预期会因返回类型不匹配编译失败,但GCC、Clang、MSVC的最新版本均能正常编译,想请教这一现象的原因。
这是因为C++允许用右值引用(A&&)来构造返回的值类型对象(A),具体逻辑如下:
std::move(rhs)的作用是把左值rhs强制转换为A&&类型的右值,它本身不会移动数据,只是改变了值的属性;- 当函数返回值类型为值类型
A时,编译器会用这个右值去调用A的移动构造函数(如果类A显式或隐式定义了移动构造);如果没有定义移动构造,则会回退调用拷贝构造函数; - 这个转换是C++标准允许的隐式行为,本质是通过移动/拷贝操作,用右值引用绑定的对象构造出一个新的
A对象作为函数返回值,因此不存在类型不匹配的编译错误。
额外提醒:第一个代码片段返回A&&的写法存在风险——返回的引用绑定到函数参数rhs,而函数结束后rhs的生命周期就会结束,这会导致返回的引用变成悬垂引用,后续使用会触发未定义行为;而第二个代码片段返回值类型A,会构造独立的新对象,不存在这个问题。
内容的提问来源于stack exchange,提问作者san216
相关产品推荐
相关产品推荐

