performance-no-automatic-move

查找由于常量性而无法自动移动的局部变量。

根据 某些条件,局部值在从函数返回时会自动移出。一个常见的错误是将局部 lvalue 变量声明为 const,这会阻止移动。

示例 [1]

StatusOr<std::vector<int>> Cool() {
  std::vector<int> obj = ...;
  return obj;  // calls StatusOr::StatusOr(std::vector<int>&&)
}

StatusOr<std::vector<int>> NotCool() {
  const std::vector<int> obj = ...;
  return obj;  // calls `StatusOr::StatusOr(const std::vector<int>&)`
}

前一个版本 (Cool) 应该优先于后一个版本 (NotCool),因为它会避免分配并可能避免大型内存复制。

语义学

在上面的例子中,StatusOr::StatusOr(T&&) 具有相同的语义,只要 T 的复制和移动构造函数具有相同的语义。请注意,不能保证 S::S(T&&)S::S(const T&) 对于任何单个 S 具有相同的语义,因此我们不会为此检查提供自动修复,并且在进行建议更改时应谨慎判断。

-Wreturn-std-move

移动无法发生的另一种情况如下

StatusOr<std::vector<int>> Uncool() {
  std::vector<int>&& obj = ...;
  return obj;  // calls `StatusOr::StatusOr(const std::vector<int>&)`
}

在这种情况下,修复方案更一致:只需 return std::move(obj)。这由 -Wreturn-std-move 警告处理。