合理使用 std::move
10.6.13 ID_unsuitableMove
std::move 的参数应为左值,返回值应直接作为接口的参数,除此之外的使用方式价值有限,且易产生错误。
左值可由 std::move 转为将亡值,宣告对象的数据即将被转移到其他对象中,将亡值和纯右值统称右值,对应转移接口的右值引用型参数。左值和将亡值也统称泛左值,具体分类依据可参见“值类别(value categories)”。
示例:
string foo();
string s = move(foo()); // Non-compliant
例中 foo 函数返回临时对象,为纯右值,move 在此处是多余的。
又如:
string a("....");
string&& b = move(a); // Non-compliant
string c(b); // Not move construction
例中 b 是具有名称的右值引用,为左值,c 仍会复制 a 的数据,move 在此处没有意义。
应改为:
string a("....");
string c(move(a)); // Compliant
这样便可将 a 的数据转移到 c 中。
又如:
string foo() {
string s;
....
return move(s); // Non-compliant
}
例中 foo 函数返回对象,编译器会进行“RVO(Return Value Optimization)”优化,使用 move 会干扰优化,故不应出现 return std::move(....) 这种代码。
应改为:
string foo() {
string s;
....
return s; // Compliant
}
依据
ISO/IEC 14882:2011 20.2.3(6)
ISO/IEC 14882:2017 23.2.5(5)