c++ - EMC++ 中提到的 "source object is lvalue"场景是什么,其中 move 语义没有提供效率增益

标签 c++ c++11 move-semantics lvalue effective-c++

来自 Effective Modern C++ 的第 29 项,Scott Meyers 列出了 move 语义不会提高代码性能的三种情况,

[…] move semantics do you no good:

  • No move operations: The object to be moved from fails to offer move operations […]
  • Move not faster: […] move operations that are no faster than its copy operations.
  • Move not usable: The context […] requires a move operation that emits no exceptions, but that operation isn't declared noexcept.

前几页都解释清楚了,再补充一个

[…] another scenario where move semantics offers no efficiency gain:

  • Source object is lvalue: With very few exceptions (see e.g. Item 25) only rvalues may be used as the source of a move operation.

(条目 25 的标题是在右值引用上使用 std::move 和在通用引用上使用 std::forward,但我不看不出它与交叉引用它的要点有什么关系。)

在此之后,文本实质上回到了对该项目的总结,没有进一步提及第四个要点。

那个要点指的是什么?

就我理解的 move 语义而言,即使我想从左值 move ,比如说 x,我仍然需要通过 std::move(x )(或等效的 static_cast),所以我在技术上仍然从右值(在这种情况下特别是 xvalue)而不是左值 move 。

所以我很想说左值不能是 move 操作的源对象。

关于这个话题我错过了什么?

最佳答案

术语 lvalue 以某种方式指代“命名”值,即具有多个引用的实体。 move 语义并不真正适用于它们,因为你不应该“窃取”可能在别处引用的东西的表示。也就是说,如果源对象是一个左值,你根本就不会 move !因此, move 构造在这里没有任何好处。事实上,左值不会自愿绑定(bind)到右值引用 - 你必须强制绑定(bind),例如,通过使用 std::move()

从本质上讲,您的观点是完全正确的:左值不能作为 move 操作的来源 - 因此 move 操作不会在涉及左值的情况下提供好处。

关于c++ - EMC++ 中提到的 "source object is lvalue"场景是什么,其中 move 语义没有提供效率增益,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65442298/

相关文章:

c# - 调用 Caffe 的 C++/CLI 包装器时出现 AccessViolationException

c++ - 在 C++ 98 中优化 vector 过滤

C++ Linux : error: ‘move’ is not a member of ‘std’ how to get around it?

c++ - std::map、std::set 和 std::priority_queue 中的比较器

c++ - 通过电线登录?

c++ - func 能拿到调用自己的lineno 吗? (C/C++)

c++ - 下标时是否必须使用 constexpr 数组?

vim - 在 vim 中无法识别 C++11 函数

c++11 - docker 中的 `npm start` 以 : Please install a supported C++11 compiler and reinstall the module 结尾

C++ move 语义和内置类型