在 C++11 中,值参数(和其他值)在返回时享受隐式移动:
A func(A a) {
return a; // uses A::A(A&&) if it exists
}
至少在 MSVC 2010 中,右值引用参数需要std::move
:
A func(A && a) {
return a; // uses A::A(A const&) even if A::A(A&&) exists
}
我想在函数内部,右值引用和值的行为类似,唯一的区别是,在值的情况下,函数本身负责销毁,而对于右值引用,责任在外部。
标准中对他们区别对待的动机是什么?
标准化委员会花费了大量精力来制定措辞,以便只有在两种情况下才会发生移动:
- 几时clearly这样做是安全的。
- 当用户明确地询问(通过
std::move
或类似的演员阵容)。
毫无疑问,值参数将在函数结束时被销毁。因此,通过移动返回显然是安全的;返回后它不能被其他代码触及(除非您故意尝试破坏事物,在这种情况下您可能会触发未定义的行为)。因此,可以在返回时将其移走。
A &&
变量可以指临时变量。但它could引用左值(命名变量)。因此它不是clearly可以安全地离开它;原始变量可能潜伏在周围。既然你没有明确地要求离开它(即:你没有打电话std::move
在此功能中),不会发生任何移动。
唯一的一次&&
变量将被隐式移动(即:没有std::move
)是当你return it. std::move<T>
返回一个T&&
。该返回值调用移动构造函数是合法的,因为它是一个返回值。
现在打电话非常困难A func(A &&a)
带有左值without呼叫std::move
(或同等演员阵容)。所以从技术上来说,它should对于参数来说很好&&
要隐式移动的类型。但标准委员会希望举措明确&&
类型,只是为了确保移动不会隐式发生在此函数的范围内。也就是说,它不能使用关于函数在哪里的函数外知识。&&
来自。
一般来说,您应该只通过以下方式获取参数&&
在两种情况下:要么您正在编写移动构造函数(或移动赋值运算符,但即使这样也可以通过值完成),要么您正在编写转发函数。可能还有其他一些情况,但您不应该采取这种情况&&
除非你有什么特别的想法。如果A
是可移动类型,那么只需按值获取即可。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)