标准化委员会花费了大量精力来创建措辞,以便仅在两种情况下才会发生动作:
- 当这样做显然是安全的。
- 当用户明确询问时(通过
std::move
或类似的演员表)。
毫无疑问,值参数将在函数结束时被销毁。因此,通过 move 将其返回显然是安全的;返回后其他代码无法触及它(除非您故意尝试破坏事物,在这种情况下您可能触发了未定义的行为)。因此,它可以从返回中移动。
&&
变量可能指的是临时变量。但它可能指的是一个左值(一个命名变量)。因此,离开它显然是不安全的;原始变量可能潜伏在周围。而且由于您没有明确要求从中移动(即:您没有调用std::move
此函数),因此不会发生移动。
唯一一次&&
隐式移动变量(即:没有std::move
)是在您返回它时。std::move<T>
返回一个T&&
。该返回值调用移动构造函数是合法的,因为它是一个返回值。
现在很难A func(A &&a)
用左值调用而不调用std::move
(或等效转换)。所以从技术上讲,隐式移动类型参数应该&&
没问题。但是标准委员会希望移动对&&
类型来说是明确的,只是为了确保移动不会隐式地发生在这个函数的范围内。也就是说,它不能使用关于&&
来自何处的函数外知识。
一般来说,你应该只&&
在两种情况下使用参数:或者你正在编写一个移动构造函数(或移动赋值运算符,但即使这也可以通过值来完成),或者你正在编写一个转发函数。&&
可能还有其他一些情况,但除非您有特别的想法,否则您不应该选择一种类型。如果A
是可移动类型,则按值取值。