当将昂贵的对象存储在一对中时,是否有必要进行 std::move
Is std::move necessary when storing an expensive object in a pair?
考虑函数中的以下代码片段:
...
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
为什么?因为临时的复制省略和返回值优化。
它也非常具有可读性。
相关文章:
- 关于std::move的使用,是否有编译警告
- 是否可以在 C++03 中定义'move-and-swap idiom'等效项
- '[](std::list& list)<int>{return std::move(list)}(list)' 是否保证将 'list' 留空?
- 是否有必要使用 std::move?这不是已经是一个右值参考了吗?
- 使用 std::move 将参数传递给函数,如果该参数声明为按值传递或使用移动操作数 &&,是否有区别?
- 编译器是否足够聪明,以至于 std::move 变量超出范围?
- 在构造函数中初始化成员时,是否应该在成员上使用 std::move?
- 在返回语句中构造对象时,std::move() 是否有助于或阻止 RVO?
- std::move 是否始终按预期工作
- 防御性地应用 std::move 到平凡可复制的类型是否不可取
- 如果对象在同一层次结构中,-Wreturn-std-move clang 警告是否正确
- 是否可以 std::move 局部堆栈变量?
- 移动变量是否有效,可以在 std::move 之后使用
- 使用 std::move 转储成员的设计是否可以接受?
- std::vector的move构造函数是否调用项的move构造器
- 是否可以将 std::move 对象移出函数?(C++11).
- std::move on std::string 是否保证 .c_str() 返回相同的结果
- 检查容器上是否完成了std::move
- std::basic_string是否正式具有隐式生成的move构造函数
- 在 std::move 之后重复使用 std 容器是否安全