当将昂贵的对象存储在一对中时,是否有必要进行 std::move

Is std::move necessary when storing an expensive object in a pair?

本文关键字:是否 move std 对象 存储      更新时间:2023-10-16

考虑函数中的以下代码片段:

...
std::string someStdString;
...
// someStdString is filled here.
...
StringWrapper wrapper {std::move(someStdString)}; // First std::move usage.
return std::pair<bool, StringWrapper> {true, std::move(wrapper)}; // Second usage.

StringWrapper 类实现所有四个复制和移动构造函数和赋值运算符,其构造函数是显式的。

std::move的第一种和第二种用法是否合理,还是其中一种或两种都没有必要?

是的,需要两个std::move来确保调用移动构造函数。简单的经验法则是"如果它有一个名字,它就是一个左值。唯一的例外是当您返回即将超出范围的自动持续时间对象时 - 此对象被视为 xvalue,并优先绑定到 move 构造函数。

std::pair<bool, StringWrapper> foo() {
  std::string someStdString;
  // ... someStdString is filled here. ...
  return {true, std::move(someStdString)};
}

我认为没有理由包含您的大部分代码,更不用说两个move了。

如果要

显式返回一对,或者在半兼容的编译器中,则std::make_pair

如上所述,StringWrapper 可以从std::string隐式创建,因此隐式创建不应混淆。

这是有效的。

return std::make_pair(true, StringWrapper { std::move(someStdString });

移动总数:1

为什么?因为临时的复制省略和返回值优化。

它也非常具有可读性。